【PHP】遇到了无数个Apache的curl配置问题【Windows】

希望这篇文章能够对Windows用户提供一些帮助。

环境

    • Windows 11

 

    • PHP 8.1.6

 

    Apache 2.4

事件的起源

我试图使用Slack API的chat.postMessage从本地主机的Apache发送。

function send_slack(string $text): void
{
    // SlackbotのtokenとchannelIDを取得
    $token = 'xoxb-XXXXXXXXXXXXXXXXXXXXX';
    $channel_id = 'XXXXXXXXXXX';
    // クエリ
    $query = 'channel='.$channel_id.'&text='.$text;
    // APIリクエストのヘッダーを作成
    $headers = [
        'Authorization: Bearer ' . $token
    ];

    // cURLを使用してAPIリクエストを送信
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'https://slack.com/api/chat.postMessage');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
    // curl_setopt($ch, CURLOPT_POSTFIELDS, "channel=$channel_id&text=$text");
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    $response = curl_exec($ch);
    curl_close($ch);

    // APIレスポンスを返す
    // echo $response;
    return;
}

运行时发生了以下错误。

Fatal error: Call to undefined function curl_init() in ...

确实,我没有设置过curl。然后我决定开始配置,并且开始工作了,但是我在搜索到的文章中很少有关于Windows的内容,大部分都是关于Linux的,所以我纠结了大约一个小时。

尝试过的事情

请在命令提示符中显示模块列表。

在命令提示符窗口中执行 php -m。

C:\Users\username>php -m
[PHP Modules]
bcmath
calendar
Core
ctype
curl
date
dom
filter
hash
iconv
json
libxml
mbstring
mysqlnd
openssl
...

[Zend Modules]

curl这个项目出现在这里,但是它没有正常工作,这可能是因为某个模块无法正确加载。
因此,需要尝试一些不同的方法。

确认PHP的设置。

image.png

检查php.ini文件

确认项目如下所示。

extension_dirがPHPのextディレクトリを指定している。

extension=curlのコメントアウトを解除している。openSSLのモジュールもついでに確認。

安装curl和openSSL

curl已经下载完成。openSSL我下载了64位版(轻量级),并安装在C:\Program Files目录下。详情略。

查找curl模块的依赖关系

使用PHP附带的deplister.exe程序。在命令提示符中导航到安装PHP的目录,然后执行以下命令。

C:\PHP>deplister.exe ext\php_curl.dll

这就是结果。

C:\PHP>deplister.exe ext\php_curl.dll
php8ts.dll,OK
libcrypto-1_1-x64.dll,OK
libssl-1_1-x64.dll,OK
CRYPT32.dll,OK
WLDAP32.dll,OK
Normaliz.dll,OK
libssh2.dll,OK
nghttp2.dll,OK
KERNEL32.dll,OK
WS2_32.dll,OK
VCRUNTIME140.dll,OK
api-ms-win-crt-heap-l1-1-0.dll,OK
api-ms-win-crt-stdio-l1-1-0.dll,OK
api-ms-win-crt-string-l1-1-0.dll,OK
api-ms-win-crt-runtime-l1-1-0.dll,OK
api-ms-win-crt-convert-l1-1-0.dll,OK
api-ms-win-crt-filesystem-l1-1-0.dll,OK
api-ms-win-crt-time-l1-1-0.dll,OK
api-ms-win-crt-utility-l1-1-0.dll,OK

如果返回的不是OK,而是NOT_FOUND之类的错误,则可能是模块不存在或损坏。安装openSSL和Visual C++可再分发包等能够解决这些文件不齐全的问题。
大部分文章似乎在这里已经解决了(?),但是我并没有解决。经过进一步的调查和研究,我最终通过以下方法使其正常运行。

在httpd.conf文件中添加附加内容。

在文件末尾添加了以下描述。

# cURL
LoadFile "C:\PHP\libssh2.dll"
LoadFile "C:\PHP\libcrypto-1_1-x64.dll"
LoadFile "C:\PHP\libssl-1_1-x64.dll"

我会在重新启动Apache之后,添加一条curl的指令到phpinfo()函数中,可以确认这是否是正确的方法,经过这样的操作,我成功地将信息发送到了Slack,问题得到解决!

刚刚当我以为结束了,却又来了一波。

Fatal error: Uncaught GuzzleHttp\Exception\RequestException: cURL error 60: SSL certificate problem: unable to get local issuer certificate (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for https://oauth2.googleapis.com/token in ...

这似乎不是发生在Slack API上,而是在调用Google Sheet API时发生的。据说有两种解决方法可供选择。

    1. 禁用SSL证书验证

 

    设置正确的根证书

由于1在安全方面不可靠,我尝试了2。

设置根证书

这次使用了提供的证书。关于如何生成自己的证书,请参考其他文章。请从下面链接下载 cacert.pem 文件。

 

将cacert.pem文件放置在合适的位置,并在php.ini中添加证书路径。我将其放置在openSSL文件夹内,所以配置如下:

curl.cainfo = "C:\Program Files\OpenSSL-Win64\cacert.pem"
广告
将在 10 秒后关闭
bannerAds