PHP 5.4 throw exception - Не удается увидеть сообщение с строковым сообщением ISO-8859-1

Недавно я установил PHP 5.4 на своем Ubuntu 12.10 из apt-get.

PHP Info показывает: PHP Version 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, и результаты были одинаковыми.

Изменить 2:

Пробовал встроенный сервер 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

Но в браузере все та же проблема.

Ответ 1

[email protected] появилось объяснение:

https://bugs.php.net/bug.php?id=63426&edit=2

Причина, по которой он не может быть исправлен, сложный, прост. Начиная с 5.4 Внутренняя кодировка PHP - это UTF-8, где раньше был латинский. Все остальное почти не изменилось.

Каждое сообщение об ошибке, отображаемое в контексте HTML, должно иметь объекты преобразованный. Для этого те же функции, что и в htmlspecialchars() используется. Где раньше PHP 5.4 он был вынужден использовать latin1, теперь это вынуждены использовать UTF8. Есть дизайн. Использование header() с content-type или default_charset влияет только на заголовок содержимого.

Таким образом, вы используете текст ошибки в latin1, но UTF-8 будет использоваться для преобразования объектов, и это будет умирать при первом недействительном char. Подходящий место в коде: http://lxr.php.net/xref/PHP_5_4/main/main.c#1083, впоследствии define_charset() предоставит UTF8 для преобразования кодировок. Это причина, по которой проглатывается ваш акцент char. А также что причина, по которой Хуэй не могла воспроизвести это, - если вы посмотрите на его пост раньше, действительно, latin1 отправляется в контентном типе, но, очевидно, использующий UTF-8 PHP скрипт, поэтому сообщение об ошибке "Fatal Ошибка: исключить исключение" Исключение "с сообщением" Ã © 'in...". текущее состояние, однако, не обязывает вас иметь скрипты в UTF-8, в вашем script, закодированном на латинском языке, вы все равно можете исключение, используя utf8_encode ('é'). Причина, по которой он работает с CLI, - это потому что никакие объекты HTML не должны быть закодированы, поэтому символы передаются как и выход.

Все это на самом деле означает, что эта проблема всегда была, но она была в пользу пользователей по умолчанию iso-8859-1. Теперь пользователи с дефолтом UTF-8 делать прибыль. Рассмотрение кодов для решения этого может потребовать более глобальное вторжение, чем требуется именно этим билетом.

Для изменения поведения htmlspecialchars() см. также ошибку # 61354

Ответ 2

Сообщение об исключении в PHP - это строка, как никакая новость для вас.

Строки в PHP являются двоичными. Это фактически означает, что PHP вообще не заботится о кодировании в нем, строки в PHP просто сохраняют любую кодировку, которая может быть выражена двоичными данными в октетах (то есть, что 8 бит образуют один байт, который затем является одним символом в строке PHP если вы используете подстрочный доступ, например, $string[10] для доступа к 11-му символу).

Как и все эти вещи, убедитесь, что, однако, вы пишете сообщение, однако оно будет передано в выход.

Таким образом, единственное различие заключается в том, как вы выводите вывод. Скажем, у вас есть кодировка Latin-1 в этой строке сообщения об исключении, и вы выводите ее через ваш сервер apache, а затем просматриваете ее в своем браузере и в браузере (на этот раз мы не заботимся о причине) отображает его как UTF-8 вы увидите, что question-mark-diagmond/crystal:.

То же самое относится к терминалу, если терминал отображает его как UTF-8.

Или, если вы сохраните вывод в файл, а затем откроете этот файл в своем редакторе как кодированный UTF-8.

Итак, как это исправить? Для вашего браузера ознакомьтесь с документацией своего браузера, как вы можете указать браузеру, в котором должна отображаться кодировка веб-сайта, который вы сейчас просматриваете. У каждого браузера, о котором я знаю, есть своеобразное меню, в котором вы можете его указать. Кодировка, которую вы используете, - commmon, поэтому даже более старые браузеры имеют это.

То же самое относится к терминалу. Вы можете установить локаль оболочки, а также кодировку для терминала. Обратитесь к документации по используемой оболочке.

Для текстового файла, я уверен, вы уже знаете, как с этим справиться: проверьте, какие параметры предоставляет ваш редактор.


Заключительное примечание: если вы хотите правильно проанализировать, что ваш сервер возвращает к запросу, содержащему вывод сообщения об исключении, вам нужно использовать инструменты разработчика вашего браузера, чтобы сделать заголовки ответов сервера видимыми. Вероятно, вы увидите изменение в вашей предыдущей конфигурации, которая (по ошибке) говорит, что контент кодируется в кодировке UTF-8, в то время как кодировка является латинской-1. Исправьте эту ошибку, если вы не хотите вручную изменять кодировку в браузере. Для этого обратитесь к документации по PHP и документации вашего веб-сервера.

Ответ 3

Вы пробовали это на другом сервере?

Я думаю, что это ваша конфигурация, я создал тестовый файл на своем сервере, вы можете просмотреть его здесь 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

Ответ 4

У меня такая же проблема и не нашел хорошего решения ( "AddCharset ISO-8859-1.php" в .htaccess не работает). Вы можете использовать это:

throw new Exception (htmlentities ('é', ENT_COMPAT, 'ISO-8859-1'));

Но Xdebug покажет:

& agrave;

Это лучше, чем ничего