google/apiclient
Official Google APIs Client Library for PHP to access services like Gmail, Drive, and YouTube from your server. PHP 8+ and Composer install supported. Library is in maintenance mode: critical bug/security fixes only, no new features.
Installation:
composer require google/apiclient
Pin google/apiclient-services to a specific version in composer.json for production stability.
First Use Case:
require_once __DIR__.'/vendor/autoload.php';
$client = new Google\Client();
$client->setApplicationName('MyApp');
$client->setDeveloperKey('YOUR_API_KEY');
$service = new Google\Service\Books($client);
$results = $service->volumes->listVolumes('PHP Laravel');
print_r($results->getItems());
Where to Look First:
examples/ directory in the package for practical examples.Authentication Patterns:
$client = new Google\Client();
$client->setAuthConfig(__DIR__.'/credentials.json');
$client->addScope(Google_Service_Drive::DRIVE);
$client->setRedirectUri('https://your-app.com/oauth2callback');
putenv('GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json');
$client = new Google\Client();
$client->useApplicationDefaultCredentials();
$client->setSubject('user@example.com'); // Impersonate a user
$client->setDeveloperKey('YOUR_API_KEY');
Service Initialization:
$drive = new Google\Service\Drive($client);
$files = $drive->files->listFiles();
Request/Response Handling:
$results = $service->methodName($params);
$request = new Google\Service\Drive\FilesCreate();
$request->setName('test.txt');
$request->setMimeType('text/plain');
$file = $drive->files->create($request, [
'data' => fopen('test.txt', 'r'),
'uploadType' => 'media',
'fields' => 'id'
]);
Pagination:
$optParams = ['pageSize' => 10, 'pageToken' => $nextPageToken];
$results = $service->list($optParams);
$nextPageToken = $results->getNextPageToken();
Error Handling:
try {
$results = $service->methodName($params);
} catch (Google\Service\Exception $e) {
if ($e->getCode() == 401) {
// Handle unauthorized
}
log::error($e->getMessage());
}
AppServiceProvider:
public function register()
{
$this->app->singleton(Google\Client::class, function ($app) {
$client = new Google\Client();
$client->setApplicationName(config('app.name'));
$client->setAuthConfig(storage_path('app/google_credentials.json'));
return $client;
});
}
public function __construct(private Google\Service\Drive $drive) {}
config/google.php and load dynamically:
$client->addScope(config('google.scopes.drive'));
Unintended API Bloat:
Google\Task\Composer::cleanup to trim dependencies.composer.json under "extra".Token Expiry:
setTokenCallback to log/handle updates:
$client->setTokenCallback(function ($cacheKey, $accessToken) {
cache()->forever($cacheKey, $accessToken);
});
Service Account Quirks:
Rate Limiting:
429 responses:
if ($e->getCode() == 429) {
sleep($e->getData()['retryAfter'] ?? 5);
retry();
}
Caching Pitfalls:
setTokenCallback alongside caching:
$client->setCache($cache);
$client->setTokenCallback($tokenCallback);
Enable Debugging:
$client->setDeveloperKey('YOUR_KEY');
$client->setDebug(true);
$client->setAccessType('offline');
stderr.Charles Proxy:
$client->setHttpClient(new \GuzzleHttp\Client([
'proxy' => 'http://localhost:8888'
]));
Common Errors:
403: Access Denied: Missing scope or incorrect credentials.401: Unauthorized: Expired token. Use fetchAccessToken() to refresh.400: Invalid Request: Malformed request body. Validate against APIs Explorer.Custom HTTP Clients: Override the default Guzzle client:
$client->setHttpClient(new CustomGuzzleClient());
Middleware: Add request/response middleware:
$client->setMiddleware([
new class implements Google\Client\Middleware {
public function __invoke($request, $next) {
$request->setHeader('X-Custom-Header', 'value');
return $next($request);
}
}
]);
Batch Requests:
Use Google\Batch\BatchRequest for parallel calls:
$batch = new Google\Batch\BatchRequest($client);
$batch->add($drive->files->get('fileId'), 'getFile');
$batch->add($drive->files->listFiles(), 'listFiles');
$responses = $batch->execute();
Laravel Integration:
$job = new SyncGoogleData($drive);
dispatch($job)->onQueue('google');
event(new GoogleDataSynced($results));
Field Selection: Reduce payload size by specifying fields:
$optParams = ['fields' => 'id,title'];
$results = $service->list($optParams);
Async Requests:
Use ReactPHP with Guzzle for non-blocking calls:
$loop = React\EventLoop\Factory::create();
$connector = new React\Guzzle\HttpClient($loop);
$client->setHttpClient($connector);
Bulk Operations:
For large datasets, use batch endpoints (e.g., Drive’s files.batchUpdate).
How can I help you explore Laravel packages today?