Облачное хранилище Google — переход на новую версию, получение объектов ‘maxResults’ для каждого префикса

#php #api #google-cloud-storage

#php #API #google-облачное хранилище

Вопрос:

Итак, мы переходим со старой версии библиотеки GCS PHP (const LIBVER = «1.0.5-beta») на более новую версию (v1.22? v0.122.0? ). Старый способ использует объект GoogleClient и производный объект Google_Service_Storage и перечисляет объекты в корзине с указанным префиксом:

 self::$client = new Google_Client();
self::$service = new Google_Service_Storage(self::$client);

$page_token = null;
$prefix = 'AR0001/file_manager/Images/';
$objects = self::$service->objects->listObjects(<bucket name>,
                                                [ 'prefix' => $prefix,
                                                  'maxResults' =>10,
                                                  'pageToken' => $page_token
                                                ]);
printf("GOT %d objectsn", count($objects['items']) );
  

В то время как более новый API имеет прямой вызов корзины для извлечения объектов:

 self::$client = new StorageClient( [
                                     'projectId' => <my project id>,
                                     'keyFile'  => <key file stuff>
                                   ]
                                 );

$bucket = self::$client->bucket( <bucket name> );

$page_token = null;
$prefix = 'AR0001/file_manager/Images/';
$objects = $my_bucket->objects( [ 'prefix'     => $prefix,
                                  'maxResults' => 10,
                                  'pageToken'  => $page_token
                                ] );
printf("GOT %d objectsn", count($objects) );
  

Я нашел исходную проблему, но это приводит к следующему — ‘maxResults’, похоже, не работает. Я установил «maxResults» в параметрах равным 10. В «старом» случае я получаю 10 результатов за вызов, а page_token позволяет мне получать все объекты по ходу работы. Но в новом случае maxResults, похоже, не работает — я получаю все 66 объектов за один раз. Я установил его равным 10, чтобы протестировать свою подкачку, но не уверен, почему это не работает для случая bucket-> objects()?

Ответ №1:

Согласно официальной документации, это рекомендуемое решение для объектов списка, использующих префикс:

 function list_objects_with_prefix($bucketName, $prefix)
{
    $storage = new StorageClient();
    $bucket = $storage->bucket($bucketName);
    $options = ['prefix' => $prefix,'resultLimit'=>2];
    foreach ($bucket->objects($options) as $object) {
        printf('Object: %s' . PHP_EOL, $object->name());
    }
}
  

В этом документе есть опция для проверки вашего префикса.

Клиентская библиотека автоматически разбивает ваши запросы на страницы по мере выполнения итерации. Итак, как вы упомянули, набор из 12 000 объектов без пользовательских настроек maxResults приведет к 12 вызовам API, если вы выполните итерацию по всему набору.

Если вам нужно перечислить несколько объектов внутри вашего bucked, клиентская библиотека автоматически разбивает ваш запрос на страницы по мере выполнения итерации. Например, если у вас в хранилище 4000 объектов, и вы не установили maxResults, вам нужно будет выполнить 4 вызова API для итерации по всему набору, поскольку в официальной документации указано, что значение maxResults по умолчанию равно 1000

Вы можете использовать настройки maxResult и resultLimit для извлечения постраничного списка объектов из корзины.

Например:

 use GoogleAuthHttpHandlerGuzzle6HttpHandler;
use GoogleCloudStorageStorageClient;
use GuzzleHttpClient;
use GuzzleHttpHandlerCurlHandler;
use GuzzleHttpHandlerStack;
use PsrHttpMessageRequestInterface;

$handler = new CurlHandler();
$stack = HandlerStack::create($handler);
$stack->push(function (callable $handler) {
    return function (RequestInterface $request, array $options) use ($handler) {
        // only write the log for calls to list objects.
        $uri = $request->getUri()->getPath();
        if (substr_compare($uri, '/o', -2) === 0) {
            echo "Requesting page" . PHP_EOL;
        }
        return $handler($request, $options);
    };
});
$client = new Client(['handler' => $stack]);

$storage = new StorageClient([
    'httpHandler' => new Guzzle6HttpHandler($client)
]);

$bucket = $storage->bucket('my-bucket');

$i = 0;
foreach ($bucket->objects(['maxResults' => 1, 'resultLimit' => 5]) as $obj) {
    $i  ;
    echo $i . ': ' . $obj->name() . PHP_EOL;
}
  

Результат будет примерно таким:

 Requesting page
1: object-a
Requesting page
2: object-b
Requesting page
3: object-c
Requesting page
4: object-d
Requesting page
5: object-e
  

Если вы хотите узнать о возможностях этой библиотеки, взгляните на этот документ.

Комментарии:

1. Спасибо, эта часть работает. Теперь я хочу выяснить, почему параметр maxResults не ограничивает то, что возвращается.

2. Спасибо, Хариф. Но я хочу отобразить свои результаты на странице — поэтому параметр «maxResults» должен это сделать (на отправленной вами странице это «Максимальное количество результатов для возврата на запрошенную страницу».) Что касается другой страницы, HTTP-запрос / ответ полезен только в том случае, если PHP API соответствует ему — я не вижу, как я пишу свой php-код для переключения между вызовами PHP и CURL. Моя проблема в том, что вызов PHP API в bucket-> objects(), похоже, работает не так, как указано в документации.

3. @AndyWallace Я редактирую свой ответ, надеюсь, он будет полезен для вас