Недавно я установил PHP 5.4 на своем Ubuntu 12.10 из apt-get.
PHP Info показывает: Версия PHP 5.4.6-1ubuntu1
Я только что установил все распространенные пакеты, такие как mysql, pgsql, curl и т. Д., Не внес никаких изменений, но у меня есть проблема.
Мне нравится использовать кодировку ISO-8859-1 / latin1 в моих файлах и базах данных, потому что именно там я получил лучший рабочий процесс. Теперь у меня проблема с этим, потому что PHP, похоже, не сочетается с исключениями, чьи сообщения закодированы таким образом.
Ну, просто для того, чтобы уточнить это лучше, я создал тестовый файл следующим образом:
ini_set('display_errors', 1); error_reporting(E_ALL); throw new Exception('é');
Если код выше находится в файле utf-8, все в порядке, с включенным Xdegub я получаю:
( ! ) Fatal error: Uncaught exception 'Exception' with message 'é' in /home/henrique/public/teste.php on line 5 ( ! ) Exception: é in /home/henrique/public/teste.php on line 5 Call Stack # Time Memory Function Location 1 0.0002 124212 {main}( ) ../teste.php:0
Если файл находится в ISO-8859-1, если Xdebug включен, проблема в том, что сообщение не отображается:
( ! ) Fatal error: in /home/henrique/public/teste.php on line 5 ( ! ) Exception: in /home/henrique/public/teste.php on line 5 Call Stack # Time Memory Function Location 1 0.0002 124436 {main}( ) ../teste.php:0
Однако, без Xdebug, все, что я получаю, – это «очень разъясняющее» сообщение:
Fatal error: in /home/henrique/public/teste.php on line 5
Возможно, это проблема в Apache, потому что, когда я пытаюсь сделать то же самое с помощью командной строки, я получаю:
Stack trace: #0 {main} thrown in /home/henrique/public/teste.php on line 5 Fatal error: Uncaught exception 'Exception' with message ' ' in /home/henrique/public/teste.php on line 5 Exception: in /home/henrique/public/teste.php on line 5 Call Stack: 0.0002 121256 1. {main}() /home/henrique/public/teste.php:0
Сообщение все еще существует, однако оно неразборчиво, но есть …
Я также пробовал с Lighttpd 1.4.28, и результаты были одинаковыми.
Пробовал встроенный сервер PHP 5.4 и получил это на моем терминале:
[Wed Jun 5 21:32:08 2013] PHP Fatal error: Uncaught exception 'Exception' with message ' ' in /var/www/test2.php:9 Stack trace: #0 {main} thrown in /var/www/test2.php on line 9 [Wed Jun 5 21:32:08 2013] 127.0.0.1:55116 [200]: /test2.php - Uncaught exception 'Exception' with message ' ' in /var/www/test2.php:9 Stack trace: #0 {main} thrown in /var/www/test2.php on line 9
Но в браузере все-таки та же проблема.
Сообщение об исключении в PHP – это строка , как никакая новость для вас.
Строки в PHP являются двоичными. Это фактически означает, что PHP вообще не заботится о кодировании в нем, строки в PHP просто сохраняют любую кодировку, которая может быть выражена двоичными данными в октетах (то есть, что 8 бит образуют один байт, который затем является одним символом в строке PHP если вы используете подстрочный доступ, например $string[10]
для доступа к 11-му символу ).
Поскольку все эти вещи гарантируют, что, однако, вы пишете сообщение, однако оно будет передано в выход.
Таким образом, единственное различие заключается в том, как вы выводите вывод. Предположим, что у вас есть кодировка Latin-1 в этой строке сообщения об исключении, и вы выводите ее через ваш сервер apache, а затем просматриваете ее в своем браузере и в браузере (на этот раз мы не заботимся о причине) отображает его как UTF-8 вы увидите, что вопросительный знак-диагмонд / кристалл: .
То же самое относится к терминалу, если терминал отображает его как UTF-8.
Или если вы сохраните вывод в файл, а затем вы откроете этот файл в своем редакторе как кодированный UTF-8.
Итак, как это исправить? Для вашего браузера ознакомьтесь с документацией своего браузера, как вы можете указать браузеру, в котором должна отображаться кодировка веб-сайта, который вы сейчас просматриваете. У каждого браузера, о котором я знаю, есть своеобразное меню, в котором вы можете его указать. Кодировка, которую вы используете, – commmon, поэтому даже более старые браузеры имеют это.
То же самое относится к терминалу. Вы можете установить локаль оболочки, а также кодировку для терминала. Обратитесь к документации по используемой оболочке.
Для текстового файла, я уверен, вы уже знаете, как с этим справиться: проверьте, какие параметры предоставляет ваш редактор.
Заключительное примечание: если вы хотите правильно проанализировать, что ваш сервер возвращает к запросу, содержащему вывод сообщения об исключении, вам нужно использовать инструменты разработчика вашего браузера, чтобы сделать заголовки ответов сервера видимыми. Вероятно, вы увидите изменение в вашей предыдущей конфигурации, которая (по ошибке) говорит, что контент кодируется в кодировке UTF-8, в то время как кодировка является латинской-1. Исправьте эту ошибку, если вы не хотите вручную изменять кодировку в браузере. Для этого обратитесь к документации по PHP и документации вашего веб-сервера.
ab@php.net придумал объяснение:
https://bugs.php.net/bug.php?id=63426&edit=2
Причина, по которой это невозможно устранить, сложна проста. Начиная с 5.4, внутренняя кодировка PHP – это UTF-8, где раньше была latin1. Все остальное почти не изменилось.
Каждое сообщение об ошибке, отображаемое в контексте HTML, должно преобразовывать сущности. Для этого используется та же функциональность, что и в htmlspecialchars (). Где раньше PHP 5.4 он был вынужден использовать latin1, теперь он вынужден использовать UTF8. Есть дизайн. Использование header () с типом контента или default_charset влияет только на назначение заголовка содержимого.
Таким образом, вы используете текст ошибки в latin1, но UTF-8 будет использоваться для преобразования объектов, и это будет умирать при первом недопустимом символе. Соответствующее место в коде: http://lxr.php.net/xref/PHP_5_4/main/main.c#1083 , впоследствии define_charset () предоставит UTF8 для кодировки преобразования. Вот почему ваш акцентный знак проглочен. И именно по этой причине Хуэй не смог воспроизвести это – если вы посмотрите на его пост раньше, действительно, latin1 отправляется в контентном типе, но, очевидно, используется сценарий PHP с кодировкой UTF-8, поэтому сообщение об ошибке «Fatal error: Uncaught исключение «Исключение» с сообщением «Ã © 'in …». Однако текущее условие не гарантирует, что у вас есть скрипты в UTF-8, в вашем скрипте, закодированном в латинском языке, вы все равно можете генерировать исключение, используя utf8_encode ('é'). Причина, по которой он работает с CLI, заключается в том, что никакие HTML-объекты не должны быть закодированы, поэтому символы передаются как выходные данные.
Все это на самом деле означает, что эта проблема всегда была там, но она была в пользу пользователей с по умолчанию iso-8859-1. Теперь пользователи с дефолтом UTF-8 получают прибыль. Рассмотрение кодов для решения этого может потребовать более глобального вторжения, чем требуется только этим билетом.
Для изменения поведения htmlspecialchars () см. Также ошибку # 61354
Вы пробовали это на другом сервере?
Я думаю, что это ваша конфигурация, я создал тестовый файл на моем сервере, вы можете просмотреть его здесь http://cai.tlacaelelrl.com/tests/test.php
содержание
ini_set('display_errors', 1); error_reporting(E_ALL); print 'Character encoding is: '.mb_internal_encoding(); throw new Exception('é');
Набор символов применяется к файлу, я также добавил набор символов в файл htaccess.
Я не уверен, что это из-за xdebug, но я не смог выполнить проверку с включенным.
Можете ли вы попробовать добавить это
AddCharset ISO-8859-1 .php
В файл .htaccess
У меня такая же проблема и не нашел хорошего решения («AddCharset ISO-8859-1 .php» в .htaccess не работает). Вы можете использовать это:
throw new Exception (htmlentities ('é', ENT_COMPAT, 'ISO-8859-1'));
Но Xdebug покажет:
&могила ;
Лучше, чем ничего