Статьи

Как долго это кусок строки?

Это вопрос, который меня беспокоил в последнее время. Хотите знать, если у кого-нибудь есть идеи, как решить эту проблему …

Функция PHP serialize () позволяет вам представлять структуры данных PHP в виде строки, которую затем можно проанализировать и восстановить в данных с помощью unserialize () .

Поскольку строку очень легко генерировать, она открывает возможность использовать ее на других языках для обмена данными с PHP, что я и делал с Javascript здесь . Другие реализации существуют в Ruby, Perl, Flash Actionscript и даже C # — собрали список тех, что я нашел здесь .

В целом, этот подход работает хорошо — по крайней мере, не нужно изобретать что-то на стороне PHP Но есть одна проблема; как долго это строка? Как показывает эта ошибка , это проблема.

Используя Javascript в качестве примера, если у меня есть строка наподобие «F“ »(« Foo »с использованием венгерского символа o — см. Здесь ) (обратите внимание, что у Sitepoint есть проблема, по-видимому, поэтому сущности обнаруживаются — вам нужно искать символ )


var s = "Főő";
alert (s.length);

Скажет мне, что длина строки равна 3 — Javascript (по крайней мере, в Mozilla / IE) умен, когда дело доходит до понимания, что такое символ.

При сериализации этой строки для PHP с использованием Javascript ее длина образует часть кодировки, которая выглядит следующим образом;


s:3:"Főő";

К сожалению, в зависимости от набора символов, используемого на сервере, на котором работает PHP, PHP не будет видеть строку как 3 символа — будет большее число — вероятно, для большинства людей 5 — PHP считает символ длиной 1 байт , Другими словами, если я просто отправлю длину строки, которую видит Javascript, функция PHP unserialize () будет жаловаться на то, что указанная длина строки не соответствует фактической длине.

Здесь есть хорошее объяснение общей проблемы Дерика (PDF). Вы можете убедиться сами, запустив следующее (убедитесь, что ваш редактор использует что-то вроде кодовой страницы Unicode — см. Глобальные свойства в SciTE );


Результат, вероятно, будет выглядеть примерно так;


s:5:"Főő";

Так как это исправить? Как мне заставить Javascript сообщать о длине строки, которая будет такой же, как ее видит PHP (количество байтов в строке)?

До сих пор я конвертировал строки в Javascript в UTF-8, который, в основном по запланированному совпадению, работает, если сервер, на котором работает PHP, использует что-то вроде ISO-8859-1 (западная Европа). Количество байтов для символа в UTF-8 обычно соответствует количеству байтов, которое он будет представлен, как в ISO-8859-1 (даже если это выглядит странно). К сожалению, это работает на Sourceforge — locale (1) на самом деле сообщает LC_CTYPE = ”en_US.UTF-8 ″ (что еще больше смущает меня и, возможно, упускает смысл).

Хотите избежать преобразований наборов символов в PHP любой ценой (для начала iconv только что стал частью стандартного дистрибутива PHP) или пытаться сообщить о локали, которую ОС использует для Javascript, так как не существует стандартного API для получения этой информации в PHP. Глядя на то, что сделали другие люди , похоже, никто не думал ни о чем, кроме US-ASCII (поэтому, к сожалению, никакого полезного вдохновения нет).

Есть идеи?

Примечание: хотя браузеры автоматически работают с кодировкой символов формы, похоже, что XmlHttpRequest в Mozilla и IE оставляет разработчику право решать, когда отправлять данные POST независимо от заданных вами заголовков HTTP-запроса (100% не подтвердили, что хоть).