今天遇到了一个很奇怪的bug,就是写了一个PHP程序,在本地运行正常,但是在发布给甲方的服务器上却无法显示验证码。具体表现为在Chorme浏览器上显示一个破裂图片的小图标。右键单击图片以在新窗口中打开它。依旧是破解的小图,不是报错信息(开启xdebug扩展和php报错的情况下),如果是这样的话,说明该URL路由和业务逻辑代码没有问题验证码。验证码生成环节有问题。我的Debug思路是这样的:1.检查GD库是否安装正确。Linux推荐使用yum或者apt或者pecl等,Windows推荐使用phpStudy的集成环境,集成了常用的扩展,只需要右键打开即可。(适用于新窗口打开时验证码图片显示错误信息和一堆乱码的情况,如有错误信息,请根据错误信息调试)2、检查调用的字体是否正确验证码丢失。验证码组件调用的部分字体未安装在目标计算机上。这就需要分析验证码模块的源码观察了。我用的是ThinkPHP官方的think-captcha。你可以在vendortopthinkthink-captchasrc中找到它的源代码。在vendortopthinkthink-captchaassets中可以看到这个验证码插件是自带字体的,所以ThinkPHP的验证码基本不用了。考虑字体问题。如果是别的验证码插件,那这个地方还是要勾选的。3、下载有bug的验证码图片和本地测试正常的验证码图片,用记事本查看对比。上图是本地环境下验证码图片的记事本。我们使用更专业的十六进制编辑器来分析文件差异。如图所示,我们发现坏文件的内容完全一样,只是前面多了一些EFBBBF等数字,说明PHP在渲染图片的时候多渲染了这些文字。代码编辑器,于是运维人员用普通的Windows记事本修改php代码,导致增加了这个BOM表头。如果是第三种原因,有两种解决方法。一种是在调用验证码的imagepng输出图片代码之前,使用ob_clean清空PHP的输出缓冲区。还有就是使用一些工具来批量去除代码的bom。我这里使用的是ob_clean,在think-captcha的主文件Captcha.php第203行前加上ob_clean(),一劳永逸。如果对性能和稳定性要求比较严格,建议使用工具批量移除bom,比较安全。同时也建议大家随时在服务器上安装专业的代码编辑器,比如editplus。不要使用Windows记事本修改代码。
