Zapic's Blog
解决Windows下PHP部分拓展无法加载的问题

又是一个巨坑,忙活了一中午.
之前搭建自己手动WAMP注意到PHP的cURL拓展没有加载,但是没怎么在意.
今天用的时候就炸掉了,然后一看phpinfo才想起来cURL没加载.
于是各种研究.

先是觉得可能是php.ini的锅,结果使用同一个php.ini,在CLI下能够加载cURL,CGI下仍然不行.
我的PHP是从官网下载的Windows版本,Thread Safe 7.2.2,但是这与问题并没有什么关系.

然后确认问题是出在CGI上之后,我去查看Apache的日志,果然炸掉了:

PHP Warning:  PHP Startup: Unable to load dynamic library 'curl' (tried: ../php-7.2.22-Win32-VC15-x64/ext\\curl (\xef\xbf\xbd\xd2\xb2\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xd6\xb8\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xc4\xa3\xef\xbf\xbd\xe9\xa1\xa3), ../php-7.2.22-Win32-VC15-x64/ext\\php_curl.dll (\xef\xbf\xbd\xd2\xb2\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xd6\xb8\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xc4\xa3\xef\xbf\xbd\xe9\xa1\xa3)) in Unknown on line 0
PHP Warning:  PHP Startup: Unable to load dynamic library 'intl' (tried: ../php-7.2.22-Win32-VC15-x64/ext\\intl (\xef\xbf\xbd\xd2\xb2\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xd6\xb8\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xc4\xa3\xef\xbf\xbd\xe9\xa1\xa3), ../php-7.2.22-Win32-VC15-x64/ext\\php_intl.dll (\xef\xbf\xbd\xd2\xb2\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xd6\xb8\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xc4\xa3\xef\xbf\xbd\xe9\xa1\xa3)) in Unknown on line 0
PHP Warning:  PHP Startup: Unable to load dynamic library 'ldap' (tried: ../php-7.2.22-Win32-VC15-x64/ext\\ldap (\xef\xbf\xbd\xd2\xb2\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xd6\xb8\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xc4\xa3\xef\xbf\xbd\xe9\xa1\xa3), ../php-7.2.22-Win32-VC15-x64/ext\\php_ldap.dll (\xef\xbf\xbd\xd2\xb2\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xd6\xb8\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xc4\xa3\xef\xbf\xbd\xe9\xa1\xa3)) in Unknown on line 0
PHP Warning:  PHP Startup: Unable to load dynamic library 'pdo_pgsql' (tried: ../php-7.2.22-Win32-VC15-x64/ext\\pdo_pgsql (\xef\xbf\xbd\xd2\xb2\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xd6\xb8\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xc4\xa3\xef\xbf\xbd\xe9\xa1\xa3), ../php-7.2.22-Win32-VC15-x64/ext\\php_pdo_pgsql.dll (\xef\xbf\xbd\xd2\xb2\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xd6\xb8\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xc4\xa3\xef\xbf\xbd\xe9\xa1\xa3)) in Unknown on line 0
PHP Warning:  PHP Startup: Unable to load dynamic library 'pgsql' (tried: ../php-7.2.22-Win32-VC15-x64/ext\\pgsql (\xef\xbf\xbd\xd2\xb2\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xd6\xb8\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xc4\xa3\xef\xbf\xbd\xe9\xa1\xa3), ../php-7.2.22-Win32-VC15-x64/ext\\php_pgsql.dll (\xef\xbf\xbd\xd2\xb2\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xd6\xb8\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xc4\xa3\xef\xbf\xbd\xe9\xa1\xa3)) in Unknown on line 0

原来不止cURL没有加载(
然后开始各种百度谷歌日志内容,发现都是说"模块不存在",但是这不能解释为什么CLI可以加载但是CGI不行.
只得想办法把\xef\xbf\xbd\xd2\xb2\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xd6\xb8\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xc4\xa3\xef\xbf\xbd\xe9\xa1\xa3什么的转成人话.
然后又是各种百度谷歌.
终于找到了一种用Python的方法:

print 'GBK字符串'.decode('gbk')

然后我满怀激动的打了进去:

[email protected]:~$ python
Python 2.7.15+ (default, Nov 27 2018, 23:36:35)
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> print '`\xef\xbf\xbd\xd2\xb2\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xd6\xb8\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xc4\xa3\xef\xbf\xbd\xe9\xa1\xa3'.decode('gbk');
`锟揭诧拷锟斤拷指锟斤拷锟斤拷模锟介。
>>>

WDNMD

我花了半个小时研究日志你给我整这个?
%^^%&^&$^&^&%#^%&*#^)

放弃日志了,继续百度...
然后看到有人说可能需要几个dll放到system32下面,叫libeay32.dll什么的,但是我并没有.
后来又看到一篇,大概是这么说的:

PHP官网说从OpenSSL 1.1.0开始cURL的依赖库改名了.
在httpd.conf里加上这几句就好了

LoadFile "D:/php-7.2.15/libssh2.dll"
LoadFile "D:/php-7.2.15/libcrypto-1_1-x64.dll"
LoadFile "D:/php-7.2.15/libssl-1_1-x64.dll"

LoadFile?
我后来又想起Windows应用加载dll的过程:

先扫描当前程序所在目录有没有,再去system32里去找
然后我就很干脆的把PHP目录下看起来像lib的dll全部拉到Apache的bin目录下面,重启Apache.
然后...
就好了.
连着其他一些没加载的拓展也加载上了.

原来这个问题只需要花一分钟解决啊草(

P.S:
如果你只需要解决cURL不能加载的问题只需要将libssh2.dll libcrypto-1_1-x64.dlllibssl-1_1-x64.dll拉过去就好了(如果你有强迫症的话

P.P.S:
如果你还是失败了,请尝试将php.ini里的extension_dir指向你的PHP目录,例如D:/php/ext.

我可去他妈的.
这个问题困扰了我大半年.
结果锅出在环境变量上.

我当时手动安装PHP时,path写进的是自己的用户环境变量.
然后...
我是以系统服务的身份启动Apache的.
这能找到我PHP的path才有鬼呢(
所以解决方案有两种:

  1. 将Apache的登录身份改为你自己的账户.
  2. 将PHP的path写进系统环境变量.

这破问题就这么简单优雅的解决了.
去他妈的LoadFile.