PHP跨文件调用带命名空间类的static main方法报错解决
我有一个GetCampaigns.php文件,其中的GetCampaigns类包含public static main()方法,该类位于Google\Ads\GoogleAds\Examples\BasicOperations命名空间下。我尝试在项目根目录的campaign-details.php中调用这个方法并获取返回结果,但运行时抛出错误:
Fatal error: Uncaught Error: Class "GetCampaigns" not found
文件路径:
GetCampaigns.php:project/google-ads-php/campaign-details.php:project/
我是OOP新手,相关代码如下:
GetCampaigns.php 代码
<?php /** * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ namespace Google\Ads\GoogleAds\Examples\BasicOperations; require __DIR__ . '/vendor/autoload.php'; use GetOpt\GetOpt; use Google\Ads\GoogleAds\Examples\Utils\ArgumentNames; use Google\Ads\GoogleAds\Examples\Utils\ArgumentParser; use Google\Ads\GoogleAds\Lib\V14\GoogleAdsClient; use Google\Ads\GoogleAds\Lib\V14\GoogleAdsClientBuilder; use Google\Ads\GoogleAds\Lib\V14\GoogleAdsException; use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder; use Google\Ads\GoogleAds\Lib\V14\GoogleAdsServerStreamDecorator; use Google\Ads\GoogleAds\V14\Errors\GoogleAdsError; use Google\Ads\GoogleAds\V14\Services\GoogleAdsRow; use Google\Ads\GoogleAds\V14\Services\SearchGoogleAdsStreamRequest; use Google\ApiCore\ApiException; use Google\Auth\FetchAuthTokenInterface; /** This example gets all campaigns. To add campaigns, run AddCampaigns.php. */ class GetCampaigns { private const CUSTOMER_ID = 1234567890; // added dummy customer id public static function main() { // Either pass the required parameters for this example on the command line, or insert them // into the constants above. $options = (new ArgumentParser())->parseCommandArguments([ ArgumentNames::CUSTOMER_ID => GetOpt::REQUIRED_ARGUMENT ]); // Generate a refreshable OAuth2 credential for authentication. $oAuth2Credential = (new OAuth2TokenBuilder())->fromFile('path to\\google_ads_php.ini')->build(); // Construct a Google Ads client configured from a properties file and the // OAuth2 credentials above. $googleAdsClient = (new GoogleAdsClientBuilder()) ->fromFile() ->withOAuth2Credential($oAuth2Credential) // We set this value to true to show how to use GAPIC v2 source code. You can remove the // below line if you wish to use the old-style source code. Note that in that case, you // probably need to modify some parts of the code below to make it work. ->usingGapicV2Source(true) ->build(); try { self::runExample( $googleAdsClient, $options[ArgumentNames::CUSTOMER_ID] ?: self::CUSTOMER_ID ); } catch (GoogleAdsException $googleAdsException) { printf( "Request with ID '%s' has failed.%sGoogle Ads failure details:%s", $googleAdsException->getRequestId(), PHP_EOL, PHP_EOL ); foreach ($googleAdsException->getGoogleAdsFailure()->getErrors() as $error) { /** @var GoogleAdsError $error */ printf( "\t%s: %s%s", $error->getErrorCode()->getErrorCode(), $error->getMessage(), PHP_EOL ); } exit(1); } catch (ApiException $apiException) { printf( "ApiException was thrown with message '%s'.%s", $apiException->getMessage(), PHP_EOL ); exit(1); } } /** * Runs the example. * * @param GoogleAdsClient $googleAdsClient the Google Ads API client * @param int $customerId the customer ID */ // [START get_campaigns] public static function runExample(GoogleAdsClient $googleAdsClient, int $customerId) { $googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient(); // Creates a query that retrieves all campaigns. $query = 'SELECT campaign.id, campaign.name, metrics.impressions, metrics.clicks, metrics.conversions, metrics.ctr, metrics.average_cpc, metrics.cost_micros FROM campaign ORDER BY campaign.id'; // Issues a search stream request. /** @var GoogleAdsServerStreamDecorator $stream */ $stream = $googleAdsServiceClient->searchStream( SearchGoogleAdsStreamRequest::build($customerId, $query) ); $campaign_details_array = array(); // Iterates over all rows in all messages and prints the requested field values for // the campaign in each row. foreach ($stream->iterateAllElements() as $googleAdsRow) { /** @var GoogleAdsRow $googleAdsRow */ $campaign_details_array[] = array('campaign_id' => $googleAdsRow->getCampaign()->getId(), 'campaign_name' => $googleAdsRow->getCampaign()->getName(), 'impressions' => $googleAdsRow->getMetrics()->getImpressions(), 'clicks' => $googleAdsRow->getMetrics()->getClicks(), 'conversions' => $googleAdsRow->getMetrics()->getConversions(), 'ctr' => $googleAdsRow->getMetrics()->getCtr(), 'average_cpc' => $googleAdsRow->getMetrics()->getAverageCpc(), 'cost_micros' => $googleAdsRow->getMetrics()->getCostMicros() ); } // print_r($campaign_details_array); // printing the array in the result return $campaign_details_array; } // [END get_campaigns] } // GetCampaigns::main(); // works fine when initialised here ?>
campaign-details.php 代码
<?php require('google-ads-php/GetCampaigns.php'); $data = GetCampaigns::main(); print_r($data); ?>
1. 核心问题:命名空间未正确引用
GetCampaigns类属于Google\Ads\GoogleAds\Examples\BasicOperations命名空间,PHP无法直接通过GetCampaigns短名称找到类,必须使用完整命名空间路径,或者通过use语句导入类。
2. 修复文件引入与自动加载
Google Ads PHP客户端依赖Composer自动加载,直接require单个文件会导致依赖类无法加载。正确做法是引入库的autoload.php文件,让Composer自动处理类加载。
修改后的campaign-details.php代码:
<?php // 引入Google Ads库的自动加载文件,确保路径正确 require __DIR__ . '/google-ads-php/vendor/autoload.php'; // 导入目标类,之后可直接用短名称调用 use Google\Ads\GoogleAds\Examples\BasicOperations\GetCampaigns; // 调用静态方法 $data = GetCampaigns::main(); print_r($data); ?>
3. 额外必要调整
(1)配置文件路径修正
GetCampaigns.php中fromFile('path to\\google_ads_php.ini')的路径需改为实际路径,若配置文件在项目根目录,修改为:
$oAuth2Credential = (new OAuth2TokenBuilder())->fromFile(__DIR__ . '/../google_ads_php.ini')->build();
__DIR__指向google-ads-php目录,../回到项目根目录。
(2)命令行参数适配
原main()方法依赖命令行参数获取客户ID,若在Web环境运行campaign-details.php,命令行参数无法获取会导致错误。可修改main()方法支持直接传入客户ID:
public static function main($customerId = null) { // 优先级:传入的ID > 命令行参数 > 类常量 $options = (new ArgumentParser())->parseCommandArguments([ ArgumentNames::CUSTOMER_ID => GetOpt::OPTIONAL_ARGUMENT ]); $finalCustomerId = $customerId ?? $options[ArgumentNames::CUSTOMER_ID] ?? self::CUSTOMER_ID; // 后续代码不变... try { return self::runExample($googleAdsClient, $finalCustomerId); } catch (...) { // 异常处理代码不变... } }
修改后可直接在调用时传入客户ID:
$data = GetCampaigns::main('1234567890');
(3)确保依赖已安装
确认google-ads-php目录下已执行composer install,生成vendor目录和自动加载文件。
内容的提问来源于stack exchange,提问作者God Uncle

