PHP 致命错误:未捕获的错误:即使在调用 autoload.php 后也找不到类“Google_Service_Gmail_Resource_Users”?

Posted

技术标签:

【中文标题】PHP 致命错误:未捕获的错误:即使在调用 autoload.php 后也找不到类“Google_Service_Gmail_Resource_Users”?【英文标题】:PHP Fatal error: Uncaught Error: Class 'Google_Service_Gmail_Resource_Users' not found even after calling autoload.php? 【发布时间】:2021-08-14 01:17:49 【问题描述】:

我收到此错误(我正在使用 php 7.0 和 Google PHP API 2.9.1,并且我正在为 Web 应用程序使用 OAuth 凭据):

Uncaught Error: Class 'Google_Service_Gmail_Resource_Users' not found in /google-api-2.9.1/vendor/google/apiclient-services/src/Google/Service/Gmail.php:106
Stack trace:
#0 /public_html/oauth2callback.php(20): Google_Service_Gmail->__construct(Object(Google\Client))
#1 main thrown in /public_html/googe-api-2.9.1/vendor/google/apiclient-services/src/Google/Service/Gmail.php on line 106

这就是我想要做的:

我的 index.php:

<?php    
include_once __DIR__ . '/google-api-2.9.1/vendor/autoload.php';
    

$client = new Google_Client();
$client->setAuthConfig(__DIR__ . 'credenciales.json');
$client->addScope(Google_Service_Gmail::GMAIL_READONLY);


if (isset($_SESSION['access_token']) && $_SESSION['access_token']) 
  $client->setAccessToken($_SESSION['access_token']);
  $gmail = new Google_Service_Gmail($client);

  $user = 'me';
  $list = $gmail->users_messages->listUsersMessages($user, [ 'q' => ['from:someEmail@gmail.com in:inbox'], ]);
  
  $messageList = $list->getMessages();
  $inboxMessage = [];
  
  foreach($messageList as $mlist)
  
      $optParamsGet2['format'] = 'full';
      $single_message = $gmail->users_messages->get('me',$mlist->id, $optParamsGet2);
  
      $message_id = $mlist->id;
      $headers = $single_message->getPayload()->getHeaders();
      $snippet = $single_message->getSnippet();
  
      foreach($headers as $single) 
  
          if ($single->getName() == 'Subject') 
  
              $message_subject = $single->getValue();
  
          
  
          else if ($single->getName() == 'Date') 
  
              $message_date = $single->getValue();
              $message_date = date('M jS Y h:i A', strtotime($message_date));
          
  
          else if ($single->getName() == 'From') 
  
              $message_sender = $single->getValue();
              $message_sender = str_replace('"', '', $message_sender);
          
      
  
  
       $inboxMessage[] = [
          'messageId' => $message_id,
          'messageSnippet' => $snippet,
          'messageSubject' => $message_subject,
          'messageDate' => $message_date,
          'messageSender' => $message_sender
      ];
  
      echo json_encode($inboxMessage);
  
    



 else 
  $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php';
  header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));

我的 oauth2callback.php 文件:

<?php
require_once __DIR__ . '/google-api-2.9.1/vendor/autoload.php';

$client = new Google_Client();
$client->setAuthConfig(__DIR__ . 'credenciales.json');
$client->setRedirectUri('https://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
$client->addScope(Google_Service_Gmail::GMAIL_READONLY);


if (! isset($_GET['code'])) 
  $auth_url = $client->createAuthUrl();
  header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
 else 
  $client->authenticate($_GET['code']);
  $_SESSION['access_token'] = $client->getAccessToken();

  $gmail = new Google_Service_Gmail($client);

  $user = 'me';
  $list = $gmail->users_messages->listUsersMessages($user, [ 'q' => ['from:someEmail@gmail.com in:inbox'], ]);
  
  $messageList = $list->getMessages();
  $inboxMessage = [];
  
  foreach($messageList as $mlist)
  
      $optParamsGet2['format'] = 'full';
      $single_message = $gmail->users_messages->get('me',$mlist->id, $optParamsGet2);
  
      $message_id = $mlist->id;
      $headers = $single_message->getPayload()->getHeaders();
      $snippet = $single_message->getSnippet();
  
      foreach($headers as $single) 
  
          if ($single->getName() == 'Subject') 
  
              $message_subject = $single->getValue();
  
          
  
          else if ($single->getName() == 'Date') 
  
              $message_date = $single->getValue();
              $message_date = date('M jS Y h:i A', strtotime($message_date));
          
  
          else if ($single->getName() == 'From') 
  
              $message_sender = $single->getValue();
              $message_sender = str_replace('"', '', $message_sender);
          
      
  
  
       $inboxMessage[] = [
          'messageId' => $message_id,
          'messageSnippet' => $snippet,
          'messageSubject' => $message_subject,
          'messageDate' => $message_date,
          'messageSender' => $message_sender
      ];
  
      echo json_encode($inboxMessage);
  
    


当我接受应用时,谷歌会带我去:

https://mywebsite.com/oauth2callback.php?code=4/8521e-kahsd875CLzcbtvppohs584ehtptRa6nXZpjhbFTDGFQjN9jgvQj_7be2E2j654ytv&scope=https://www.googleapis.com/auth/gmail.readonly

所以,我去通过 Google 的授权屏幕,我接受我的应用程序,然后是一个空白屏幕。显示的错误来自错误日志文件。

为什么在调用自动​​加载文件时找不到“Google_Service_Gmail_Resource_Users”类?

【问题讨论】:

/librerias/google-api-2.9.1/vendor/autoload.php 是从哪里来的?假设它是由 Composer 放在那里的,你应该从项目的根目录运行它,而不是库的文件夹。 此外,您的库文件也不应位于可公开访问的文件下。这意味着您的网络服务器的简单配置错误会向公众公开您的应用配置等敏感数据。 所以cd /var/www/html/myapp/ &amp;&amp; composer require google/apiclient。然后在您的 PHP require_once("/var/www/html/myapp/vendor/autoload.php"); 中配置您的 Web 服务器以使用 /var/www/html/myapp/public 作为文档根目录,并将面向公众的文件放在那里。删除librerias 目录。 感谢 cmets。我没有使用作曲家,它只是一个演示服务器,我只是想让它工作。但是你的建议很好,所以我又开始了,这次没有使用任何 librerias 文件夹。我相应地更新了问题。 好的,我在 github 存储库中没有看到供应商文件夹,所以我想你是在之后添加的。我想说无论如何,使用作曲家会让事情变得更容易。看起来下载的版本包含一个预安装的 Composer 供应商目录。 【参考方案1】:

所以我发现您当前的设置存在一些问题。与您的问题有关的是您没有使用 Composer。它小巧、简单且易于使用,并为您处理所有自动加载的内容。不用担心丢失目录或解压缩错误。 Google API 客户端的download version 已经包含一个预构建的 Composer 供应商文件夹,因此您不会通过跳过它来节省任何磁盘空间或代码复杂性。

其次是你的目录结构;根据您的服务器设置方式,某人访问https://mywebsite.example.com/credenciales.json 并获取您的私人数据是微不足道的。

所以这是我的建议:

在您的文档根 (/var/www/html/home_dir) 中创建一个 public 文件夹并将 index.phpoauth2callback.php 复制到该文件夹​​。 更新您的服务器配置以指向 /var/www/html/home_dir/public 作为您的文档根目录 更改为 /var/www/html/home_dir 并运行 composer require google/apiclient(install Composer,如果你还没有) 根据需要编辑您的 PHP 文件,将路径调整为 credentiales.json 并将您的 require 指令更改为指向 /var/www/html/home_dir/vendor/autoload.php

【讨论】:

以上是关于PHP 致命错误:未捕获的错误:即使在调用 autoload.php 后也找不到类“Google_Service_Gmail_Resource_Users”?的主要内容,如果未能解决你的问题,请参考以下文章

PHP“致命错误:未捕获错误:调用成员函数prepare()为null”

PHP 致命错误:未捕获的错误:在 PHP 7.2.13 上调用未定义函数 idn_to_ascii()

PHP 致命错误:未捕获的错误:调用字符串中的成员函数 diff()

PHP 致命错误:未捕获的错误:使用 Laravel 5.8 和 PHP 7.4 调用未定义函数 Whoops\Exception\xdebug_is_enabled()

致命错误:未捕获的错误:在 C:\xampp\phpMyAdmin\libraries\classes\DatabaseInterface.php:1544 中的 null 上调用成员函数存在()

致命错误:未捕获的错误:在 null 上调用成员函数 select()