Ini adalah bagaimana Anda dapat membersihkan sistem file seperti yang diminta
function filter_filename($name) {
// remove illegal file system characters https://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words
$name = str_replace(array_merge(
array_map('chr', range(0, 31)),
array('<', '>', ':', '"', '/', '\\', '|', '?', '*')
), '', $name);
// maximise filename length to 255 bytes http://serverfault.com/a/9548/44086
$ext = pathinfo($name, PATHINFO_EXTENSION);
$name= mb_strcut(pathinfo($name, PATHINFO_FILENAME), 0, 255 - ($ext ? strlen($ext) + 1 : 0), mb_detect_encoding($name)) . ($ext ? '.' . $ext : '');
return $name;
}
Segala sesuatu yang lain diperbolehkan dalam filesystem, jadi pertanyaannya terjawab dengan sempurna ...
... tetapi bisa berbahaya untuk mengizinkan, misalnya tanda kutip tunggal '
dalam nama file jika Anda menggunakannya nanti dalam konteks HTML yang tidak aman karena nama file ini benar-benar legal:
' onerror= 'alert(document.cookie).jpg
menjadi lubang XSS :
<img src='<? echo $image ?>' />
// output:
<img src=' ' onerror= 'alert(document.cookie)' />
Karena itu, perangkat lunak CMS Wordpress yang populer menghapusnya, tetapi mereka menutupi semua karakter yang relevan hanya setelah beberapa pembaruan :
$special_chars = array("?", "[", "]", "/", "\\", "=", "<", ">", ":", ";", ",", "'", "\"", "&", "$", "#", "*", "(", ")", "|", "~", "`", "!", "{", "}", "%", "+", chr(0));
// ... a few rows later are whitespaces removed as well ...
preg_replace( '/[\r\n\t -]+/', '-', $filename )
Terakhir, daftar mereka sekarang menyertakan sebagian besar karakter yang merupakan bagian dari karakter yang dilindungi URI dan daftar karakter URL yang tidak aman .
Tentu saja Anda dapat dengan mudah menyandikan semua karakter ini pada keluaran HTML, tetapi sebagian besar pengembang dan saya juga, mengikuti ungkapan "Lebih baik aman daripada menyesal" dan menghapusnya terlebih dahulu.
Jadi akhirnya saya menyarankan untuk menggunakan ini:
function filter_filename($filename, $beautify=true) {
// sanitize filename
$filename = preg_replace(
'~
[<>:"/\\|?*]| # file system reserved https://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words
[\x00-\x1F]| # control characters http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx
[\x7F\xA0\xAD]| # non-printing characters DEL, NO-BREAK SPACE, SOFT HYPHEN
[#\[\]@!$&\'()+,;=]| # URI reserved https://tools.ietf.org/html/rfc3986#section-2.2
[{}^\~`] # URL unsafe characters https://www.ietf.org/rfc/rfc1738.txt
~x',
'-', $filename);
// avoids ".", ".." or ".hiddenFiles"
$filename = ltrim($filename, '.-');
// optional beautification
if ($beautify) $filename = beautify_filename($filename);
// maximize filename length to 255 bytes http://serverfault.com/a/9548/44086
$ext = pathinfo($filename, PATHINFO_EXTENSION);
$filename = mb_strcut(pathinfo($filename, PATHINFO_FILENAME), 0, 255 - ($ext ? strlen($ext) + 1 : 0), mb_detect_encoding($filename)) . ($ext ? '.' . $ext : '');
return $filename;
}
Segala sesuatu yang lain yang tidak menyebabkan masalah dengan sistem file harus menjadi bagian dari fungsi tambahan:
function beautify_filename($filename) {
// reduce consecutive characters
$filename = preg_replace(array(
// "file name.zip" becomes "file-name.zip"
'/ +/',
// "file___name.zip" becomes "file-name.zip"
'/_+/',
// "file---name.zip" becomes "file-name.zip"
'/-+/'
), '-', $filename);
$filename = preg_replace(array(
// "file--.--.-.--name.zip" becomes "file.name.zip"
'/-*\.-*/',
// "file...name..zip" becomes "file.name.zip"
'/\.{2,}/'
), '.', $filename);
// lowercase for windows/unix interoperability http://support.microsoft.com/kb/100625
$filename = mb_strtolower($filename, mb_detect_encoding($filename));
// ".file-name.-" becomes "file-name"
$filename = trim($filename, '.-');
return $filename;
}
Dan pada titik ini Anda perlu membuat nama file jika hasilnya kosong dan Anda dapat memutuskan apakah Anda ingin menyandikan karakter UTF-8. Tetapi Anda tidak membutuhkannya karena UTF-8 diizinkan di semua sistem file yang digunakan dalam konteks hosting web.
Satu-satunya hal yang harus Anda lakukan adalah menggunakan urlencode()
(seperti yang Anda harapkan dengan semua URL Anda) sehingga nama file საბეჭდი_მანქანა.jpg
menjadi URL ini sebagai Anda <img src>
atau <a href>
:
http://www.maxrev.de/html/img/%E1%83% A1% E1% 83% 90% E1% 83% 91% E1% 83% 94% E1% 83% AD% E1% 83% 93% E1% 83% 98_% E1% 83% 9B% E1% 83% 90% E1% 83% 9C% E1% 83% A5% E1% 83% 90% E1% 83% 9C% E1% 83% 90.jpg
Stackoverflow melakukan itu, jadi saya dapat memposting tautan ini seperti yang dilakukan pengguna:
http://www.maxrev.de/html/img/ საბეჭდი_მანქანა. Jpg
Jadi ini adalah nama file resmi yang lengkap dan bukan masalah seperti yang disebutkan @ SequenceDigitale.com dalam jawabannya .