система php, python и utf-8 - PullRequest
       48

система php, python и utf-8

3 голосов
/ 09 сентября 2011

У меня очень хорошо работает программа на Python. Он подключается к нескольким веб-сайтам и выводит необходимую информацию. Так как не все сайты кодируются с помощью utf-8, я запрашиваю кодировку из заголовков и использую метод unicode(string, encoding) для декодирования (я не уверен, является ли это подходящим способом, но он работает довольно хорошо). Когда я запускаю программу Python, я получаю нет ??? отмечает, и это работает отлично. Но когда я запускаю программу, используя php system, я получаю эту ошибку:

UnicodeEncodeError: 'ascii' codec can't encode character u'\u0131' in position 41: ordinal not in range(128)

Это ошибка, специфичная для python, но меня смущает то, что я не получаю эту ошибку, когда запускаю программу с помощью терминала. Я получаю это только когда использую функцию php system и вызываю программу из php. Что может быть причиной этой проблемы?

Вот пример кода:

PHP-код, который вызывает программу на Python:

system("python somefile.py $search") // where $search is the variable coming from an input

код питона:

encoding = "iso-8859-9"
l = "some string here with latin characters"
print unicode("<div class='line'>%s</div>" % l, encoding)
# when I run this code from terminal it works perfect and I receive no ??? marks
# when I run this code from php, I receive the error above

Ответы [ 2 ]

3 голосов
/ 09 сентября 2011

Из PrintFails wiki :

Когда Python обнаруживает, что его вывод подключен к терминалу, он устанавливает атрибут sys.stdout.encoding для кодировки терминала.Обработчик оператора print автоматически закодирует аргументы юникода в вывод str.

Вот почему ваша программа работает при вызове из терминала.

Когда Python не обнаруживает желаемыйнабор символов для вывода, он устанавливает sys.stdout.encoding в None, и print вызовет кодек "ascii".

Вот почему ваша программа завершается ошибкой при вызове из php.Чтобы это работало при вызове из php, вам нужно явно указать, какую кодировку print следует использовать.Например, чтобы явно указать, что вы хотите, чтобы выход был закодирован в utf-8 (если он не подключен к терминалу):

ENCODING = sys.stdout.encoding if sys.stdout.encoding else 'utf-8'
print unicode("<div class='line'>%s</div>" % l, encoding).encode(ENCODING)

В качестве альтернативы, вы можете установить переменную среды PYTHONIOENCODING .Тогда ваш код должен работать без изменений (как из терминала, так и при вызове из php).

2 голосов
/ 09 сентября 2011

Когда вы запускаете скрипт python в своем терминале, ваш терминал, вероятно, будет закодирован в UTF8 (особенно если вы используете linux или mac).

Когда вы установите l переменную на "some string with latin characters", эта строка будет закодирована в кодировку по умолчанию, если вы используете терминал, l будет UTF8 и сценарий не будет аварийно завершаться.

Небольшой совет: если у вас есть строка, закодированная в latin1, и вы хотите ее в Unicode, вы можете сделать:

variable.decode('latin1')

...