Замешано: fopen PHP не работает на шестнадцатеричных символах в 5.3.1 / WIN - PullRequest
0 голосов
/ 25 февраля 2011

У меня неожиданная проблема с php при попытке декодировать URL-адреса iTunes в имена файловых систем. Itunes дает мне следующее расположение для имени файла, созданного для проверки совместимости с UTF8.

Файл: // локальный / C: / Users / пользователя / Desktop /% E6% 9D% BF% C3% AD% E9% 87% 8E% E5% 8F% 8B% E7% BE% 8E% D0% B8 % C3% B0% D0% B9% C3% до н.э.% C3% B6 +% CF% 88% E6% до н.э.% А2% E8% АА% 9E% E7% АЕ% 80% D8% B1% D7% 91% D6% B5 % D6% BC% D7% 99% D8% A8% D9% 8A.mp3

оригинальное имя файла представляет собой смесь букв и символов: 板 í 野 友 美 andðйüö + ψ 漢語 简 ر בֵּי بي. Mp3

Я преобразовал это в формат строки php и удалил файл: // 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 \ xÀ2 \ X Е8 \ Хаа \ x9E \ xE7 \ XAE \ x80 \ xD8 \ XB1 \ xD7 \ x91 \ xD6 \ XB5 \ xD6 \ XBC \ xD7 \ x99 \ xD8 \ xA8 \ xD9 \ x8A.mp3"

при попытке открыть ($ filename, 'r'); Windows жалуется, что файл не существует.

Это на PHP5.3.1 (XAMPP) на Windows.

Ответы [ 2 ]

0 голосов
/ 25 февраля 2011

У меня нет сейчас окна Windows с PHP для тестирования, но я думаю, что ваша проблема, скорее всего, в том, что кодировка имени в 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.

0 голосов
/ 25 февраля 2011

+, если не экранировано, означает пробел в 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);
...