困惑:PHP 的 fopen 在 5.3.1/WIN 中的十六进制字符上失败

发布于 2024-10-19 13:28:18 字数 709 浏览 1 评论 0原文

我在尝试将 iTunes URL 解码为文件系统名称时遇到了 php 的意外问题。 Itunes 为我提供了以下位置的文件名,用于测试 UTF8 兼容性。

文件://localhost/C:/Users/user/Desktop/%E6%9D%BF%C3%AD%E9%87%8E%E5%8F%8B%E7%BE%8E%D0%B8%C3% B0%D0%B9%C3%BC%C3%B6+%CF%88%E6%BC%A2%E8%AA%9E%E7%AE%80%D8%B1%D7%91%D6%B5%D6% BC%D7%99%D8%A8%D9%8A.mp3

原始文件名是字母和字符的混合: 板í野友美иðйüö+ψ汉语简瑞בֵּבּּй.mp3

我已将其转换为 php 的字符串格式并剥离文件: //loaclhost/前缀: $文件名 = "C:/Users/用户/桌面/\xE6\x9D\xBF\xC3\xAD\xE9\x87\x8E\xE5\x8F\x8B\xE7\xBE\x8E\xD0\xB8\xC3\xB0\ xD0\xB9\xC3\xBC\xC3\xB6+\xCF\x88\xE6\xBC\xA2\xE8\xAA\x9E\xE7\xAE\x80\xD8\xB1\xD7\x91\xD6\xB5\xD6\xBC\ xD7\x99\xD8\xA8\xD9\x8A.mp3"

当我尝试 fopen( $filename, 'r' ); windows 抱怨该文件不存在。

这是 Windows 上的 PHP5.3.1 (XAMPP)。

I'm having an unexpected problem with php in my attempt to decode iTunes URLs into filesystem names. Itunes gives me the following location for a filename crafted to test UTF8 compatibility.

file://localhost/C:/Users/user/Desktop/%E6%9D%BF%C3%AD%E9%87%8E%E5%8F%8B%E7%BE%8E%D0%B8%C3%B0%D0%B9%C3%BC%C3%B6+%CF%88%E6%BC%A2%E8%AA%9E%E7%AE%80%D8%B1%D7%91%D6%B5%D6%BC%D7%99%D8%A8%D9%8A.mp3

original filename is a mix of alphabets and chars: 板í野友美иðйüö+ψ漢語简رבֵּיبي.mp3

I have converted that to php's string format and stripped the file://loaclhost/ prefix:
$filename = "C:/Users/user/Desktop/\xE6\x9D\xBF\xC3\xAD\xE9\x87\x8E\xE5\x8F\x8B\xE7\xBE\x8E\xD0\xB8\xC3\xB0\xD0\xB9\xC3\xBC\xC3\xB6+\xCF\x88\xE6\xBC\xA2\xE8\xAA\x9E\xE7\xAE\x80\xD8\xB1\xD7\x91\xD6\xB5\xD6\xBC\xD7\x99\xD8\xA8\xD9\x8A.mp3"

when I attempt to fopen( $filename, 'r' ); windows complains that the file doesn't exist.

This is on PHP5.3.1 (XAMPP) on Windows.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

美男兮 2024-10-26 13:28:18

+,除非转义,否则表示 URL 中存在空格。因此,Windows 正确地声明该文件不存在,因为它包含空格,而不是 +

与其尝试自己解码 URL,为什么不使用提供的已建立的 urldecode()通过 PHP?

$iTunesURI = 'file://localhost/C:/Users/user/Desktop/%E6%9D%BF%C3%AD%E9%87%8E%E5%8F%8B%E7%BE%8E%D0%B8%C3%B0%D0%B9%C3%BC%C3%B6+%CF%88%E6%BC%A2%E8%AA%9E%E7%AE%80%D8%B1%D7%91%D6%B5%D6%BC%D7%99%D8%A8%D9%8A.mp3';
$iTunesPath = ltrim(parse_url($iTunesURI, PHP_URL_PATH), '/');

$filename = urldecode($iTunesPath);

+, unless escaped, means space in the URL. Windows is therefore properly stating that the file doesn't exist since it contains a space, not a +.

Instead of attempting to decode the URL yourself, why not use the established urldecode() provided by PHP?

$iTunesURI = 'file://localhost/C:/Users/user/Desktop/%E6%9D%BF%C3%AD%E9%87%8E%E5%8F%8B%E7%BE%8E%D0%B8%C3%B0%D0%B9%C3%BC%C3%B6+%CF%88%E6%BC%A2%E8%AA%9E%E7%AE%80%D8%B1%D7%91%D6%B5%D6%BC%D7%99%D8%A8%D9%8A.mp3';
$iTunesPath = ltrim(parse_url($iTunesURI, PHP_URL_PATH), '/');

$filename = urldecode($iTunesPath);
池予 2024-10-26 13:28:18

我现在没有带有 PHP 的 Windows 盒子来测试,但我认为你的问题可能是 Windows 中的文件名编码通常为 UTF-16。 Undex Linux,使用 ext3 文件系统,我创建了您指定的文件名,然后编写了以下 PHP 文件(以 UTF-8 编码):

<?php
$filename = "板í野友美иðйüö+ψ漢語简رבֵּיبي.mp3";
$fh = fopen($filename, 'r');
$contents = fread($fh, filesize($filename));
print $contents;
var_dump($filename);
fclose($fh);

function encode_filename($fname) {

    $replaced_filename =
        preg_replace_callback(
            '/[^\x20-\x7F]/',
            create_function(
                '$matches',
                'return "\x" . dechex(ord($matches[0]));'
            ),
            $fname
        );
    return $replaced_filename;

}

print "Encoded UTF-8 filename: " . encode_filename($filename) . "\n";

$filename = mb_convert_encoding($filename, "UTF-8", "UTF-16");
print "Encoded UTF-16 filename: " . encode_filename($filename) . "\n";

?>

它成功读取了我的目标文件并输出了其内容。

编码文件名的输出是:

Encoded UTF-8 filename: \xe6\x9d\xbf\xc3\xad\xe9\x87\x8e\xe5\x8f\x8b\xe7\xbe\x8e\xd0\xb8\xc3\xb0\xd0\xb9\xc3\xbc\xc3\xb6+\xcf\x88\xe6\xbc\xa2\xe8\xaa\x9e\xe7\xae\x80\xd8\xb1\xd7\x91\xd6\xb5\xd6\xbc\xd7\x99\xd8\xa8\xd9\x8a.mp3
Encoded UTF-16 filename: \xee\x9a\x9d\xeb\xbf\x83\xea\xb7\xa9\xe8\x9e\x8e\xee\x96\x8f\xe8\xaf\xa7\xeb\xba\x8e\xed\x82\xb8\xec\x8e\xb0\xed\x82\xb9\xec\x8e\xbc\xec\x8e\xb6\xe2\xaf\x8f\xe8\xa3\xa6\xeb\xb2\xa2\xee\xa2\xaa\xe9\xbb\xa7\xea\xba\x80\xed\x9e\x91\xed\x9a\xb5\xed\x9a\xbc\xed\x9e\x99\xe2\xb9\xad\xe7\x80\xb3

这与您的 UTF-8 编码相匹配,因此看起来是正确的。尝试使用 UTF-16 编码。或者,像我一样,将文件名直接嵌入到文件中,并以 UTF-16 编码文件。

I don't have a Windows box with PHP on it right now to test, but I think your problem is likely that the filename encoding in Windows is normally UTF-16. Undex Linux, using an ext3 filesystem, I created the filename you indicated, then wrote the following PHP file (encoded in UTF-8):

<?php
$filename = "板í野友美иðйüö+ψ漢語简رבֵּיبي.mp3";
$fh = fopen($filename, 'r');
$contents = fread($fh, filesize($filename));
print $contents;
var_dump($filename);
fclose($fh);

function encode_filename($fname) {

    $replaced_filename =
        preg_replace_callback(
            '/[^\x20-\x7F]/',
            create_function(
                '$matches',
                'return "\x" . dechex(ord($matches[0]));'
            ),
            $fname
        );
    return $replaced_filename;

}

print "Encoded UTF-8 filename: " . encode_filename($filename) . "\n";

$filename = mb_convert_encoding($filename, "UTF-8", "UTF-16");
print "Encoded UTF-16 filename: " . encode_filename($filename) . "\n";

?>

It successfully read my target file and outputted its contents.

The output for the encoded filenames was:

Encoded UTF-8 filename: \xe6\x9d\xbf\xc3\xad\xe9\x87\x8e\xe5\x8f\x8b\xe7\xbe\x8e\xd0\xb8\xc3\xb0\xd0\xb9\xc3\xbc\xc3\xb6+\xcf\x88\xe6\xbc\xa2\xe8\xaa\x9e\xe7\xae\x80\xd8\xb1\xd7\x91\xd6\xb5\xd6\xbc\xd7\x99\xd8\xa8\xd9\x8a.mp3
Encoded UTF-16 filename: \xee\x9a\x9d\xeb\xbf\x83\xea\xb7\xa9\xe8\x9e\x8e\xee\x96\x8f\xe8\xaf\xa7\xeb\xba\x8e\xed\x82\xb8\xec\x8e\xb0\xed\x82\xb9\xec\x8e\xbc\xec\x8e\xb6\xe2\xaf\x8f\xe8\xa3\xa6\xeb\xb2\xa2\xee\xa2\xaa\xe9\xbb\xa7\xea\xba\x80\xed\x9e\x91\xed\x9a\xb5\xed\x9a\xbc\xed\x9e\x99\xe2\xb9\xad\xe7\x80\xb3

This matches your UTF-8 encoding, so that seems right. Try the UTF-16 encoding. Or, do like I did, and embed the filename directly in the file and encode the file in UTF-16.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文