使用GoogleClient获取Access Token时遇cURL error 2问题求助
这个错误我之前碰到过好几次,核心原因就是同一个cURL easy handle被重复绑定到了multi handle中,而Google Client底层的Guzzle HTTP客户端如果复用实例的话,很容易触发这个冲突。下面给你几个靠谱的解决办法:
每次请求都新建Google Client实例
这是最稳妥的方案,不要全局复用同一个$client对象,尤其是在处理授权码回调的时候,重新初始化一个干净的实例:// 初始化全新的Client实例 $client = new Google_Client(); $client->setClientId('你的客户端ID'); $client->setClientSecret('你的客户端密钥'); $client->setRedirectUri('你的回调地址'); $client->addScope(['email', 'profile']); if (isset($_GET['code'])) { try { $accessToken = $client->fetchAccessTokenWithAuthCode($_GET['code']); // 这里处理令牌存储、用户信息获取等逻辑 } catch (Exception $e) { // 捕获错误做日志或提示 error_log($e->getMessage()); } }为什么要这么做?因为如果之前的Client实例已经发起过请求,内部的cURL资源可能已经被关联到multi handle上,重复使用就会触发冲突。
如果必须复用实例,先重置HTTP客户端
要是因为业务需求不得不复用Client对象,那在调用fetchAccessTokenWithAuthCode之前,手动重置底层的HTTP客户端,清理掉旧的cURL资源:// 假设$client是之前创建的实例 $client->getHttpClient()->reset(); $accessToken = $client->fetchAccessTokenWithAuthCode($_GET['code']);Google Client依赖Guzzle,
reset()方法会彻底清空之前的请求状态和cURL handle,避免资源冲突。排查项目中其他cURL操作
检查你的代码里有没有其他地方手动使用了curl_multi_init()这类multi handle操作。如果有,要确保这些操作和Google Client的令牌请求不在同一个请求周期内执行——比如不要在处理谷歌回调的同一个脚本里,同时运行批量cURL请求,这会导致handle被重复绑定。
另外还要注意:绝对不要把Google Client对象序列化后存在Session或者缓存里,序列化会丢失cURL资源的状态,再次反序列化使用时必然会出问题。
内容的提问来源于stack exchange,提问作者shihab mm

