sanitize_file_name()
云策文档标注
概述
sanitize_file_name() 函数用于清理文件名,移除非法字符、替换空格为短横线,并处理文件名首尾的特定字符。它通过过滤器允许插件自定义清理行为,但不保证返回的文件名一定可上传。
关键要点
- 移除操作系统非法字符和命令行需转义的特殊字符,如 ?、[、]、/、 等。
- 将空格和连续短横线替换为单个短横线,并修剪文件名首尾的句点、短横线和下划线。
- 支持两个过滤器:sanitize_file_name_chars 用于自定义移除字符列表,sanitize_file_name 用于修改清理后的文件名。
- 处理非 UTF-8 编码文件名时,会使用 sanitize_title_with_dashes() 进行转换。
- 函数不保证返回的文件名在所有文件系统上都可上传,开发者需根据需求进一步验证。
代码示例
// 示例:使用 sanitize_file_name() 清理文件名
$filename = "test file?.txt";
$sanitized = sanitize_file_name($filename);
// 输出:test-file.txt注意事项
- 函数内部依赖 wp_is_valid_utf8()、remove_accents() 等辅助函数,确保环境支持。
- 对于多扩展名文件名,函数会检查每个部分是否匹配允许的 MIME 类型,不匹配时添加下划线。
- 用户贡献笔记提供了额外用法,如通过过滤器将文件名转换为小写或增强 ASCII 兼容性。
原文内容
Sanitizes a filename, replacing whitespace with dashes.
Description
Removes special characters that are illegal in filenames on certain operating systems and special characters requiring special escaping to manipulate at the command line. Replaces spaces and consecutive dashes with a single dash. Trims period, dash and underscore from beginning and end of filename. It is not guaranteed that this function will return a filename that is allowed to be uploaded.
Parameters
$filenamestringrequired-
The filename to be sanitized.
Source
function sanitize_file_name( $filename ) {
$filename_raw = $filename;
$filename = remove_accents( $filename );
$special_chars = array( '?', '[', ']', '/', '\', '=', '<', '>', ':', ';', ',', "'", '"', '&', '$', '#', '*', '(', ')', '|', '~', '`', '!', '{', '}', '%', '+', '’', '«', '»', '”', '“', chr( 0 ) );
if ( ! wp_is_valid_utf8( $filename ) ) {
$_ext = pathinfo( $filename, PATHINFO_EXTENSION );
$_name = pathinfo( $filename, PATHINFO_FILENAME );
$filename = sanitize_title_with_dashes( $_name ) . '.' . $_ext;
}
if ( _wp_can_use_pcre_u() ) {
/**
* Replace all whitespace characters with a basic space (U+0020).
*
* The “Zs” in the pattern selects characters in the `Space_Separator`
* category, which is what Unicode considers space characters.
*
* @see https://www.unicode.org/reports/tr44/#General_Category_Values
* @see https://www.unicode.org/versions/Unicode16.0.0/core-spec/chapter-6/#G17548
* @see https://www.php.net/manual/en/regexp.reference.unicode.php
*/
$filename = preg_replace( '#p{Zs}#siu', ' ', $filename );
}
/**
* Filters the list of characters to remove from a filename.
*
* @since 2.8.0
*
* @param string[] $special_chars Array of characters to remove.
* @param string $filename_raw The original filename to be sanitized.
*/
$special_chars = apply_filters( 'sanitize_file_name_chars', $special_chars, $filename_raw );
$filename = str_replace( $special_chars, '', $filename );
$filename = str_replace( array( '%20', '+' ), '-', $filename );
$filename = preg_replace( '/.{2,}/', '.', $filename );
$filename = preg_replace( '/[rnt -]+/', '-', $filename );
$filename = trim( $filename, '.-_' );
if ( ! str_contains( $filename, '.' ) ) {
$mime_types = wp_get_mime_types();
$filetype = wp_check_filetype( 'test.' . $filename, $mime_types );
if ( $filetype['ext'] === $filename ) {
$filename = 'unnamed-file.' . $filetype['ext'];
}
}
// Split the filename into a base and extension[s].
$parts = explode( '.', $filename );
// Return if only one extension.
if ( count( $parts ) <= 2 ) {
/** This filter is documented in wp-includes/formatting.php */
return apply_filters( 'sanitize_file_name', $filename, $filename_raw );
}
// Process multiple extensions.
$filename = array_shift( $parts );
$extension = array_pop( $parts );
$mimes = get_allowed_mime_types();
/*
* Loop over any intermediate extensions. Postfix them with a trailing underscore
* if they are a 2 - 5 character long alpha string not in the allowed extension list.
*/
foreach ( (array) $parts as $part ) {
$filename .= '.' . $part;
if ( preg_match( '/^[a-zA-Z]{2,5}d?$/', $part ) ) {
$allowed = false;
foreach ( $mimes as $ext_preg => $mime_match ) {
$ext_preg = '!^(' . $ext_preg . ')$!i';
if ( preg_match( $ext_preg, $part ) ) {
$allowed = true;
break;
}
}
if ( ! $allowed ) {
$filename .= '_';
}
}
}
$filename .= '.' . $extension;
/**
* Filters a sanitized filename string.
*
* @since 2.8.0
*
* @param string $filename Sanitized filename.
* @param string $filename_raw The filename prior to sanitization.
*/
return apply_filters( 'sanitize_file_name', $filename, $filename_raw );
}
Hooks
- apply_filters( ‘sanitize_file_name’, string $filename, string $filename_raw )
-
Filters a sanitized filename string.
- apply_filters( ‘sanitize_file_name_chars’, string[] $special_chars, string $filename_raw )
-
Filters the list of characters to remove from a filename.
Changelog
| Version | Description |
|---|---|
| 2.1.0 | Introduced. |
Skip to note 4 content
Muhammad Jawad Abbasi
When you write any special characters in a filename like brackets, commas etc then that function sanitize_file_name() automatically remove from that file name.
For Example:
In above code use bracket and comma after that sanitize_file_name() function remove bracket and comma then show final result is test.php
Skip to note 5 content
Stefan Pejcic
You can also use sanitize_file_name to automatically convert all filenames on upload to lowercase:
add_filter( 'sanitize_file_name', 'mb_strtolower' );Skip to note 6 content
John Dorner
“It is not guaranteed that this function will return a filename that is allowed to be uploaded.”
The following code should make it so the returned filename is allowed on all file systems.
This requires both the mbstring and iconv PHP modules be installed.
add_filter( 'sanitize_file_name', 'wpdocs_sanitize_filename' ); function wpdocs_sanitize_filename( $text ) { if ( 'ASCII' !== mb_detect_encoding( $text ) ) { // convert $text to ASCII $step1 = iconv( mb_detect_encoding( $text ), 'ASCII//TRANSLIT', $text ); // replace spaces and unknown characters with hyphens $step2 = sanitize_file_name( $step1 ); $text = $step2; } return $text; }