Google_Client在PHP8环境下的兼容报错及登录修复求助
PHP8环境下Google API登录兼容问题修复方案
问题描述
通过composer require google/apiclient安装google/apiclient ^2.0版本后,在PHP8环境中使用Google_Client实现登录时,不同PHP版本触发以下兼容错误:
- PHP8.0:
Fatal error: Uncaught TypeError: count(): Argument #1 ($value) must be of type Countable|array, null given in C:\wamp64\www\.....\vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php on line 67 - PHP8.1.13及8.2.0:
Deprecated: Return type of Google_Model::offsetExists($offset) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in C:\wamp64\www\....\vendor\google\apiclient\src\Google\Model.php on line 249
尽管官方宣称google/apiclient支持PHP7.4+,但检测到$_POST['credential']时仍出现上述问题,开发环境为Windows11下的WAMP。
相关代码
index.php
<html lang="en"> <body> <?php require_once 'class.GoogleLogin.php'; $google=new GoogleLogin(); $google->handleGooglePosts(); echo $google->getGoogleScriptInclude();
class.GoogleLogin.php
<?php require_once 'class.config.php'; class GoogleLogin { public function getGoogleScriptInclude() { return "<script src='https://accounts.google.com/gsi/client' async defer></script>"; } //-------------------------------------------------------------------------------- public function getGoogleLoginTags() { $redirect=config::google_redirectUri; return " <div id='g_id_onload' data-client_id='".config::google_clientId."' data-login_uri='$redirect' data-auto_prompt='false'> </div> <div class='g_id_signin' data-type='standard' data-size='large' data-theme='outline' data-text='sign_in_with' data-shape='rectangular' data-logo_alignment='left'> </div> "; } //-------------------------------------------------------------------------------- Final public function handleGooglePosts() { $site=config::siteURL; $redirect=$_SERVER['REQUEST_URI']; if ( isset($_POST['credential'])) { $id_token = $_POST['credential']; require_once 'autoload.php'; $client = new Google_Client(['client_id' => config::google_clientId]); if ( !$client ) { echo "<LI>No client";exit; } $guzzleClient = new \GuzzleHttp\Client(array('curl' => array(CURLOPT_SSL_VERIFYPEER => false,),)); $client->setHttpClient($guzzleClient); try { $payload = $client->verifyIdToken($id_token); } catch (Exception $e) { echo "<LI>Exception ".$e->getMessage(); exit; } . . exit;
修复方案
1. 修复PHP8.0的count()类型错误
该错误源于google/apiclient依赖的GuzzleHttp版本过低,不兼容PHP8.0的类型校验规则。
- 执行Composer命令升级Guzzle到兼容版本:
composer require guzzlehttp/guzzle:^7.4 - 同时调整Guzzle客户端的创建代码(更符合Guzzle 7+规范,本地开发临时关闭SSL验证,生产环境建议开启):
$guzzleClient = new \GuzzleHttp\Client([ 'verify' => false, // 生产环境改为true或指定SSL证书路径 ]);
2. 修复PHP8.1+的返回类型兼容警告
该警告是因为Google_Model类实现ArrayAccess接口时,offsetExists方法未遵循PHP8.1+的返回类型声明要求,有两种修复方式:
方式一:升级google/apiclient到最新2.x版本(推荐)
官方在2.15+版本中已修复此兼容性问题,执行升级命令:
composer update google/apiclient
方式二:手动修改源码(临时方案)
如果暂时无法升级,可直接修改vendor/google/apiclient/src/Google/Model.php的第249行:
- 方案A:添加bool返回类型声明
public function offsetExists(mixed $offset): bool - 方案B:添加属性抑制警告
#[\ReturnTypeWillChange] public function offsetExists($offset)
代码优化建议
- 提前引入自动加载文件:不要在
handleGooglePosts方法内才引入autoload.php,建议在index.php开头就添加:require_once 'vendor/autoload.php'; - 增强凭证校验:处理
$_POST['credential']时,增加合法性校验:$id_token = filter_input(INPUT_POST, 'credential', FILTER_SANITIZE_STRING); if (!$id_token) { exit('无效的登录凭证'); }
内容的提问来源于stack exchange,提问作者abe1432181
相关产品推荐
相关产品推荐

