php, python и utf-8

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

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

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

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

php-код, который вызывает программу python:

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

код python:

 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 

Из Википедии PrintFails :

Когда Python находит свой вывод, подключенный к терминалу, он устанавливает атрибут sys.stdout.encoding в кодировку терминала. Обработчик инструкции print автоматически кодирует аргументы в unicode в 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).

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

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

Маленький совет: если у вас есть строка, закодированная в latin1, и вы хотите ее использовать в юникоде, вы можете сделать:

variable.decode('latin1')