昨天从早晨8点一直到凌晨1点都在和PHP程序较劲,先前还好,是一些简单的问题,我使用面向错误的编程方法,哪里出错弄哪里,大概还算顺利。
(图源 :pixabay)
可是后来遇到一个超级奇怪的BUG,简单描述就是:一个查询函数,传入中文参数,查询不到结果,传入英文参数则一切正常。
为了解决这个问题,我至少读了网络上上百篇文章,把所有建议尝试的方法都尝试过了,也没能解决。我还跑去微信群里求救,大家也给出一堆建议,但是我测试来测试去还是没有眉目,抓狂不已!
甚至我怀疑是系统或者库函数版本的问题,老系统是bantu 20.04+PHP7.4,我又新开了个VPS运行Ubantu 18.04+PHP7.2 ,结果问题依旧。
为了证实不是远端服务器的问题,我又用Python重写了一下代码,结果Python运行的结果就是正常的。
然后我用PHP CLI试着运行一下我的PHP脚本,你猜怎着,PHP命令行运行出来的结果也是正常的!这就令人诧异了,PHP CLI运行正常,网页运行却不正常,到底哪里出问题了呢?
我首先想到的PHP.INI设置的问题,然后用diff
命令比较了一下相对应的PHP.INI:
diff /etc/php/7.2/cli/php.ini /etc/php/7.2/apache2/php.ini
结果发现两者基本上没有啥差异。
然后我朋友说是网页编码问题导致的,可能是传递的参数在处理过程中编码变了。我也觉得是编码问题,为此我特意测试了一下查询语句(输入变量)的编码:
echo mb_detect_encoding($query);
var_dump($query);
结果无论是PHP CLI还是网页运行,显示的类型都是UTF-8 string(81)
,内容也完全一致。也就是说至少和我网页的编码以及输入内容的编码无关,问题出在我调用的函数内部。
这个函数是PHP的函数,我没法调试进去,于是我就想,输入一致,设置一致,还有什么能影响到函数的计算过程及结果呢?大概只有运行环境了。而PHP CLI以及网页运行,其实是不同的环境,一个是本地环境,一个是Apache的运行环境。
而影响编码的往往应该和语言设置有关,LANG啥的,对比一下php -i | grep LANG
的命令行输出和phpinfo()的网页输出,发现差异了:
所以,尽管都是PHP程序,但是使用命令行方式还是网页方式运行,还是存在差异的。知道可能是这个问题导致的程序BUG,我开始着手解决,但是使用一堆设置环境变量的函数也没设置明白。
最后使用发现可以编辑/etc/apache2/envvars
,将export LANG=C
修改为如下内容:
export LANG=en_US.UTF-8
重启Apache,程序正常执行,搞定!花了我近17个小时啊,全是眼泪!其实要研究下去还是可以继续研究下去的,比如到底能不能在脚本中通过设置环境变量解决?LANG=XXXX
是如何影响到程序运行的?不过实在是太累了,不想弄了身心俱疲。
另外,吐槽一下,明明一个封装好的函数,到第三方服务器去查询,竟然会和环境变量有依赖,真是醉了!大坑无处不在啊!