最近在一個項目中需要用到php下的curl
擴展,但是在實際運行時遭遇到了curl函數無法執行的問題,頁面錯誤為:
Call to undefined function curl_init();
環境配置:
- windows 10 64bit
- Apache 2.4(win32)
- php 5.6.21 ts
按照常規步驟檢查
- 用
phpinfo()
找到php.ini文件路徑 -
extension_dir
是否配置正確 -
extension=php_curl.dll
是否打開
結果一切正常,但是phpinfo()
的結果里沒有curl模塊
然后用搜的,網上大多數的解決方案是:
- 把
libeay32.dll
,ssleay32.dll
放進system32
里,重啟apache,還有的說要把php5ts.dll
也放進去,最接近的是把libssh2.dll
放進<Apache dir>/bin里 - 考慮php版本號和
php_curl.dll
的版本號是否一致 - 可能要用到
libcurl.dll
庫 - 檢查apache的重啟姿勢,不能只用
httpd -k restart
,還要從系統服務里重啟
最后朋友給出一種終極方法:把現在的環境干掉,找個集成環境重新裝一遍!
這也是個辦法,可是我不想重裝,咋辦?
另外,我還發現了一個奇怪的現象,我在command line下檢查加載的模塊時,curl是可以加載的,并且可以執行。但是用phpinfo()
就是顯示沒有加載。
接著就再放狗查這個現象,然而沒有什么有用的信息。
一個偶然的想法,去看了apache的日志,發現一行:
PHP Warning: PHP Startup: Unable to load dynamic library 'C:\\Server\\php\\ext\\php_curl.dll' - The operating system cannot run %1.\r\n in Unknown on line 0
根據apache的錯誤日志,大概能看出來,這是操作系統沒有找到對應的動態鏈接庫。
于是放狗,打開php官方的一篇文檔:PHP: 安裝 - Manual,查找The operating system cannot run %1.\r\n
,找到標題是mtudor AT icefusion remove me DOT co uk ?
的一篇帖子內容,在這篇發布于7年前的帖子里,他講述了遇到的一個跟這個問題幾乎一致的現象!,并對這個問題給出了詳細的分析、產生的原因和解決方法。
其中在原因一節,他這樣寫道:
CAUSE
-----
This was caused by PHP picking up the WRONG VERSIONS of libeay.dll and ssleay.dll, which were present in multiple locations on my computer.
When any application attempts to use a dll file in windows, the system searches for this file using the following order:
- The directory from which the application loaded.
- The windows\system32 directory.
- The windows\system directory.
- The windows directory.
- The current directory.
- The directories that are listed in the PATH environment variable.
(http://msdn.microsoft.com/en-us/library/ms682586.aspx)
For PHP running under Apache, the application directory is <apache dir>\bin and NOT <php dir>. PHP was finding OUT OF DATE versions of libeay.dll and ssleay.dll in <apache dir>\bin (probably installed when I enabled SSL support in my web server). Because of this, the latest versions in windows\system32 were never reached.
他主要分析了windows系統查找動態鏈接庫文件的順序,注意到其中的一段話:
**For PHP running under Apache, the application directory is <apache dir>\bin and NOT <php dir>. **
這說明apache可能需要在自己的運行環境里找到libeay32.dll
,ssleay32.dll
和php_curl.dll
這幾個文件,但我們并沒有把它們從php文件夾下拷到apache/bin下,而是放到了windows/system32中,而并卵。
糾正以后,終于看到了熟悉的結果。而這也正好解釋了我能在command line下可以執行curl_init()
,但用phpinfo()
函數看不到的現象。