Php 比较readdir()和_FILE__;之间的文件名,使用法语重音

Php 比较readdir()和_FILE__;之间的文件名,使用法语重音,php,character-encoding,Php,Character Encoding,我有一个网站,它的PHP收集与当前脚本相同目录中的所有其他文件,并由此生成一个菜单(此菜单包括运行脚本的当前文件) 当我从这个文件名列表生成这个菜单的HTML时,我会检查每个文件名是否等于当前文件名(通过_; file _;)。如果是这样,我将应用样式在菜单中高亮显示该项 我的文件名带有法语口音,因为文件名也用于页面标题。这在Chrome和Firefox中运行良好,但Safari和IOS不起作用;法语口音把这个过程搞得一团糟,因为从我的文件名中删除法语口音可以解决这个问题 这是我的密码: 从当前

我有一个网站,它的PHP收集与当前脚本相同目录中的所有其他文件,并由此生成一个菜单(此菜单包括运行脚本的当前文件)

当我从这个文件名列表生成这个菜单的HTML时,我会检查每个文件名是否等于当前文件名(通过_; file _;)。如果是这样,我将应用样式在菜单中高亮显示该项

我的文件名带有法语口音,因为文件名也用于页面标题。这在Chrome和Firefox中运行良好,但Safari和IOS不起作用;法语口音把这个过程搞得一团糟,因为从我的文件名中删除法语口音可以解决这个问题

这是我的密码:

从当前目录获取所有相关文件

if ($handle = opendir(getcwd())) {
    $albums = array();
    while (false !== ($entry = readdir($handle))) {
        if(is_numeric(substr($entry, 0, 4))) array_push($albums, $entry);
    }
    closedir($handle);
}
这是我的字符串比较,简化了,与它们的var_转储比较:(未添加文件名清理,假设两个变量都提供名称文件名结构)

当我试图强制他们使用UTF_8或ASCII,看看他们如何处理法语口音时,他们会以不同的方式转换口音,但我不知道是什么原因造成了这种情况。这是我用来获取fileanmes(_uuu文件,readdir())的方法吗

我的HTML文件是utf-8,以防这很重要。将我的PHP专门设置为UTF-8也不能解决问题

编辑

<?php echo bin2hex($albums[$i]); echo '<br/>'.bin2hex($originFilename);?>

在这两个字符串中,第一个十六进制字符串是正确的

给定十六进制编码的输出,我们可以看到这两个字符串的不同之处。第一个读数为
65cc80
,第二个读数为
c3a8
。这表明你是暴力的受害者

第一个序列对应于两个Unicode字符
U+0065
()和
U+0300
()。如您所见,将它们的UTF-8编码形式连接在一起可以得到十六进制编码的字节序列
0x65cc80

第二个序列对应于单个Unicode字符
U+00E8
(),该字符编码为
0xc3a8

这里的情况是,您有两个字节序列,它们不是位相同的,但是根据Unicode规则,它们在逻辑上是等价的。当您想要比较字符串时,您需要一个编码和规范化感知的比较函数,或者需要事先规范化字符串(然后可以使用哑比较函数,例如字符串相等)


不幸的是,我不知道如何在PHP中进行逻辑等价性比较,因此解决方案是安装intl扩展,并使用类将两个字符串转换为规范化形式C。

给定十六进制编码的输出,我们可以看到两个字符串的不同之处。第一个读数为
65cc80
,第二个读数为
c3a8
。这表明你是暴力的受害者

第一个序列对应于两个Unicode字符
U+0065
()和
U+0300
()。如您所见,将它们的UTF-8编码形式连接在一起可以得到十六进制编码的字节序列
0x65cc80

第二个序列对应于单个Unicode字符
U+00E8
(),该字符编码为
0xc3a8

这里的情况是,您有两个字节序列,它们不是位相同的,但是根据Unicode规则,它们在逻辑上是等价的。当您想要比较字符串时,您需要一个编码和规范化感知的比较函数,或者需要事先规范化字符串(然后可以使用哑比较函数,例如字符串相等)


不幸的是,我不知道如何在PHP中进行逻辑等价性比较,因此解决方案是安装intl扩展,并使用类将两个字符串转换为规范化形式C。

echo var_dump(…)
?!?什么…@pruspus:使用
bin2hex
来查看到底有什么区别。我不知道浏览器如何在这里发挥作用,这是一个纯粹的服务器端代码。一定还有别的问题。也许你试图在url中传递“页面名称”时遇到了编码问题?@Jon,显然十六进制长度不相等。重音字母需要额外的字节吗?这会计入额外的十六进制值吗?@arkascha我同意,但显然值得指出的是,它们与某些浏览器一起工作,而与其他浏览器不工作。我开始怀疑“FILE”是直接从脚本还是从请求头(从浏览器发送)提取文件名,从而导致浏览器使用的编码/字符集的依赖性?
echo var\u dump(…)
?!?什么…@pruspus:使用
bin2hex
来查看到底有什么区别。我不知道浏览器如何在这里发挥作用,这是一个纯粹的服务器端代码。一定还有别的问题。也许你试图在url中传递“页面名称”时遇到了编码问题?@Jon,显然十六进制长度不相等。重音字母需要额外的字节吗?这会计入额外的十六进制值吗?@arkascha我同意,但显然值得指出的是,它们与某些浏览器一起工作,而与其他浏览器不工作。我开始怀疑_; FILE _;是直接从脚本还是从请求头(从浏览器发送)提取文件名,从而导致浏览器使用的编码/字符集的依赖性?
string(26) "2010_Kalymnos,_Grèce.php" 
string(25) "2010_Kalymnos,_Grèce.php" 
<?php echo bin2hex($albums[$i]); echo '<br/>'.bin2hex($originFilename);?>
323031305f4b616c796d6e6f732c5f477265cc8063652e706870
323031305f4b616c796d6e6f732c5f4772c3a863652e706870