php - PHP字符串重音字符更改
问题描述
我使用 elFinder 作为 PHP 连接器 ( elFinder 文档) 的文件浏览器,我已经为 Sanitizer 插件 ( Sanitizer 插件) 配置了一个回调函数。
function sanitize($filename){ // Or @callable sanitize function
$a = pathinfo($filename);
$b = strtourl($a['filename'],false).'.'.$a['extension'];
echo $b;
return $b;
}
function strtourl($str, $toLower = true){
$sr = array('À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Æ', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï', 'Ð', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', 'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', 'ß', 'à', 'á', 'â', 'ã', 'ä', 'å', 'æ', 'ç', 'è', 'é', 'ê', 'ë', 'ì', 'í', 'î', 'ï', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', 'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'ÿ', 'Ā', 'ā', 'Ă', 'ă', 'Ą', 'ą', 'Ć', 'ć', 'Ĉ', 'ĉ', 'Ċ', 'ċ', 'Č', 'č', 'Ď', 'ď', 'Đ', 'đ', 'Ē', 'ē', 'Ĕ', 'ĕ', 'Ė', 'ė', 'Ę', 'ę', 'Ě', 'ě', 'Ĝ', 'ĝ', 'Ğ', 'ğ', 'Ġ', 'ġ', 'Ģ', 'ģ', 'Ĥ', 'ĥ', 'Ħ', 'ħ', 'Ĩ', 'ĩ', 'Ī', 'ī', 'Ĭ', 'ĭ', 'Į', 'į', 'İ', 'ı', 'IJ', 'ij', 'Ĵ', 'ĵ', 'Ķ', 'ķ', 'Ĺ', 'ĺ', 'Ļ', 'ļ', 'Ľ', 'ľ', 'Ŀ', 'ŀ', 'Ł', 'ł', 'Ń', 'ń', 'Ņ', 'ņ', 'Ň', 'ň', 'ʼn', 'Ō', 'ō', 'Ŏ', 'ŏ', 'Ő', 'ő', 'Œ', 'œ', 'Ŕ', 'ŕ', 'Ŗ', 'ŗ', 'Ř', 'ř', 'Ś', 'ś', 'Ŝ', 'ŝ', 'Ş', 'ş', 'Š', 'š', 'Ţ', 'ţ', 'Ť', 'ť', 'Ŧ', 'ŧ', 'Ũ', 'ũ', 'Ū', 'ū', 'Ŭ', 'ŭ', 'Ů', 'ů', 'Ű', 'ű', 'Ų', 'ų', 'Ŵ', 'ŵ', 'Ŷ', 'ŷ', 'Ÿ', 'Ź', 'ź', 'Ż', 'ż', 'Ž', 'ž', 'ſ', 'ƒ', 'Ơ', 'ơ', 'Ư', 'ư', 'Ǎ', 'ǎ', 'Ǐ', 'ǐ', 'Ǒ', 'ǒ', 'Ǔ', 'ǔ', 'Ǖ', 'ǖ', 'Ǘ', 'ǘ', 'Ǚ', 'ǚ', 'Ǜ', 'ǜ', 'Ǻ', 'ǻ', 'Ǽ', 'ǽ', 'Ǿ', 'ǿ');
$rp = array('A', 'A', 'A', 'A', 'A', 'A', 'AE', 'C', 'E', 'E', 'E', 'E', 'I', 'I', 'I', 'I', 'D', 'N', 'O', 'O', 'O', 'O', 'O', 'O', 'U', 'U', 'U', 'U', 'Y', 's', 'a', 'a', 'a', 'a', 'a', 'a', 'ae', 'c', 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i', 'n', 'o', 'o', 'o', 'o', 'o', 'o', 'u', 'u', 'u', 'u', 'y', 'y', 'A', 'a', 'A', 'a', 'A', 'a', 'C', 'c', 'C', 'c', 'C', 'c', 'C', 'c', 'D', 'd', 'D', 'd', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'G', 'g', 'G', 'g', 'G', 'g', 'G', 'g', 'H', 'h', 'H', 'h', 'I', 'i', 'I', 'i', 'I', 'i', 'I', 'i', 'I', 'i', 'IJ', 'ij', 'J', 'j', 'K', 'k', 'L', 'l', 'L', 'l', 'L', 'l', 'L', 'l', 'l', 'l', 'N', 'n', 'N', 'n', 'N', 'n', 'n', 'O', 'o', 'O', 'o', 'O', 'o', 'OE', 'oe', 'R', 'r', 'R', 'r', 'R', 'r', 'S', 's', 'S', 's', 'S', 's', 'S', 's', 'T', 't', 'T', 't', 'T', 't', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'W', 'w', 'Y', 'y', 'Y', 'Z', 'z', 'Z', 'z', 'Z', 'z', 's', 'f', 'O', 'o', 'U', 'u', 'A', 'a', 'I', 'i', 'O', 'o', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'A', 'a', 'AE', 'ae', 'O', 'o');
$url = $str;
if($toLower) $url = strtolower($url);
$url = preg_replace('/\s+/', "-", $url);
$url = str_replace($sr, $rp, $url);
$url = preg_replace('/[^a-zA-Z0-9_.-]+/i', "-", $url);
$url = preg_replace('/-{2,}/', "-", $url);
$url = preg_replace('/-+$/', "", $url);
return $url;
}
如果我使用自定义字符串手动调用此函数,则效果很好。如果我在插件调用时将 $filename 替换为自定义字符串,则它可以完美运行。
但是当任何函数触及字符串时,从插件到达的文件名会被修改。让我解释。
插件 -> sanitize("Camión Avión.jpg")
如果我注释所有内容并回显 $filename,则输出是预期的Camión Avión.jpg
,但如果我取消注释所有内容并在函数开头回显 $filename,则输出为CamioÌn AvioÌn.jpg
,但在回显 $filename 之前什么都没有。
让我们继续前进,如果我删除我的自定义函数 strtourl() 并尝试下一个:
function Sanitize($filename){
var_dump($filename);
var_dump($filename{5});
var_dump($filename{6});
var_dump($filename{7});
}
结果是:
string(20) "CamioÌn AvioÌn.jpg"
string(1) "Ì"
string(1) ""
string(1) "n"
在 ascii UTF-8 中,“Ì”是 204,“”是 129 代码。
如果我评论 las 3 行:
function Sanitize($filename){
var_dump($filename);
//var_dump($filename{5});
//var_dump($filename{6});
//var_dump($filename{7});
}
结果是:string(20) "Camión Avión.jpg"
我不知道会发生什么,有人可以帮助我吗?
谢谢你。
解决方案
最后正如@JosefZ 评论的那样,这是一个规范化问题。elFinder 连接器也提供了一个插件来规范文件名,然后再对其进行清理。规范器插件
这是我的最终配置:
$opts = array(
'bind' => array(
'upload.pre mkdir.pre mkfile.pre rename.pre archive.pre ls.pre' => array(
'Plugin.Normalizer.cmdPreprocess',
'Plugin.Sanitizer.cmdPreprocess'
),
'upload.presave paste.copyfrom' => array(
'Plugin.Normalizer.onUpLoadPreSave',
'Plugin.Sanitizer.onUpLoadPreSave'
)
),
'roots' => array(
array(
'driver' => 'LocalFileSystem',
'path' => ROOT_PATH,
'URL' => URI.ROOT,
"trashHash" => "t2_Lw",
'alias' => $_ENV['WEBID'],
'attributes' => $attrs,
'plugin' => array(
'Normalizer' => array(
'enable' => true,
'nfc' => true,
'nfkc' => true,
'umlauts' => false,
'lowercase' => false,
'convmap' => array()
),
'Sanitizer' => array(
'enable' => true,
'targets' => array('\\','/',':','','?','"','<','>','|'), // target chars
'replace' => '_', // replace to this
'callBack' => '\App\Admin\Controllers\Sanitize'
)
)
),
array(
'id' => '2',
'driver' => 'Trash',
'path' => ROOT_PATH . '/.papelera',
)
),
'maxTargets' => string2bool($_POST['multiple']) ? null : 1,
'debug' => DEBUG,
'locale' => 'es_ES.UTF-8',
'tmbBgColor' => '#FFFFFF',
'tmbCrop' => false
);
使用这个 elFinder 连接器选项和之前的函数(strtourl 和 sanitize 回调),它可以按预期工作。
请注意,Normalizer 插件使用需要 intl 扩展的 PHP Normalizer 类。我在 Xampp for Mac 上安装它时遇到了一些麻烦,但我发现这篇文章解决了这个问题。Mac 上 Xammp 的 Intl
推荐阅读
- monitoring - 如何使用 Graphite 监控 AWS SQS - Grafana
- android - 如何在 android firebase 聊天中显示打字指示器
- javascript - 访问 JS DOM 内部的函数参数
- excel - #从excel复制并使用VBA粘贴到记事本
- jquery - 将 2 个 html 文件添加到我的一页滚动站点
- c# - 如何在不使用 SqlDependency 的情况下从存储过程中使用 SQL Server Service Broker 触发 C# 方法?
- perl - 使用参数运行子程序
- createjs - createjs loadManifest,它应该在清单中加载文件,对吗?
- python - Scrapy没有返回结果
- wix-react-native-navigation - React Native Navigation - 底部选项卡溢出