Đây là cách bạn có thể làm sạch hệ thống tệp khi được yêu cầu
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;
}
Mọi thứ khác đều được phép trong hệ thống tệp, vì vậy câu hỏi được trả lời hoàn hảo ...
... nhưng có thể nguy hiểm nếu cho phép các dấu ngoặc kép ví dụ'
trong tên tệp nếu bạn sử dụng nó sau này trong ngữ cảnh HTML không an toàn vì tên tệp hoàn toàn hợp pháp này:
' onerror= 'alert(document.cookie).jpg
trở thành một lỗ XSS :
<img src='<? echo $image ?>' />
// output:
<img src=' ' onerror= 'alert(document.cookie)' />
Do đó, phần mềm CMS phổ biến Wordpress sẽ loại bỏ chúng, nhưng chúng chỉ bao gồm tất cả các ký tự liên quan sau một số bản cập nhật :
$special_chars = array("?", "[", "]", "/", "\\", "=", "<", ">", ":", ";", ",", "'", "\"", "&", "$", "#", "*", "(", ")", "|", "~", "`", "!", "{", "}", "%", "+", chr(0));
// ... a few rows later are whitespaces removed as well ...
preg_replace( '/[\r\n\t -]+/', '-', $filename )
Cuối cùng, danh sách của họ bây giờ bao gồm hầu hết các ký tự là một phần của các ký tự được khôi phục lại URI và các ký tự không an toàn cho URL danh sách.
Tất nhiên bạn có thể đơn giản mã hóa tất cả các ký tự này trên đầu ra HTML, nhưng hầu hết các nhà phát triển và tôi cũng vậy, hãy làm theo câu thành ngữ "An toàn hơn là xin lỗi" và xóa chúng trước.
Vì vậy, cuối cùng tôi đề nghị sử dụng cái này:
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;
}
Mọi thứ khác không gây ra sự cố với hệ thống tệp phải là một phần của chức năng bổ sung:
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;
}
Và tại thời điểm này, bạn cần tạo tên tệp nếu kết quả trống và bạn có thể quyết định xem mình có muốn mã hóa các ký tự UTF-8 hay không. Nhưng bạn không cần điều đó vì UTF-8 được phép trong tất cả các hệ thống tệp được sử dụng trong bối cảnh lưu trữ web.
Điều duy nhất bạn phải làm là sử dụng urlencode()
(như bạn hy vọng sẽ làm điều đó với tất cả các URL của mình) để tên tệp საბეჭდი_მანქანა.jpg
trở thành URL này là của bạn <img src>
hoặc <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 thực hiện điều đó, vì vậy tôi có thể đăng liên kết này như một người dùng sẽ làm điều đó:
http://www.maxrev.de/html/img/ საბეჭდი_მანქანა. Jpg
Vì vậy, đây là một tên tệp hợp pháp hoàn chỉnh và không phải là một vấn đề như @ SequenceDigitale.com đã đề cập trong câu trả lời của anh ấy .