PHP系统、Python与UTF-8
我有一个运行得很好的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
函数调用程序时,才会出现这个问题。这可能是什么原因呢?
以下是一个示例代码:
调用Python程序的PHP代码:
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
2 个回答
当你在终端运行Python脚本时,你的终端很可能是用UTF8编码的(特别是如果你在使用Linux或Mac的话)。
当你把变量l
设置为"一些包含拉丁字符的字符串"
时,这个字符串会按照默认编码进行编码。如果你在终端中,l
的编码就是UTF8,这样脚本就不会崩溃。
小贴士:如果你有一个用latin1编码的字符串,想把它转换成unicode格式,你可以这样做:
variable.decode('latin1')
来自PrintFails wiki的内容:
当Python发现它的输出连接到一个终端时,它会把
sys.stdout.encoding
这个属性设置为终端的编码方式。这样,打印语句就会自动把Unicode类型的内容转换成字符串输出。
这就是为什么你的程序在终端中运行时能够正常工作的原因。
当Python没有检测到合适的字符集时,它会把
sys.stdout.encoding
设置为None,这时打印就会使用“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调用时都正常工作,而不需要做其他修改。