Usar carregamentos facionados do Amazon S3 com o AWS SDK para PHP versão 3 - AWS SDK para PHP

Usar carregamentos facionados do Amazon S3 com o AWS SDK para PHP versão 3

Com uma única operação PutObject, você pode fazer upload de objetos de até 5 GB. No entanto, usando os métodos de multipart upload (por exemplo CreateMultipartUpload, UploadPart, CompleteMultipartUpload, AbortMultipartUpload), você pode fazer upload de objetos de 5 MB a 5 TB.

O exemplo a seguir mostra como:

  • Faça upload de um objeto no Amazon S3 usando ObjectUploader.

  • Crie um carregamento fracionado para um objeto do Amazon S3 usando MultipartUploader.

  • Copie objetos de um local do Amazon S3 para outro usando ObjectCopier.

O código de exemplo completo do AWS SDK para PHP está disponível aqui no GitHub.

Credenciais

Antes de executar o código de exemplo, configure suas credenciais da AWS, conforme descrito em Autenticar com a AWS usando o AWS SDK para PHP versão 3. Em seguida, importe o AWS SDK para PHP, conforme descrito em Instalar o AWS SDK para PHP versão 3.

Uploader de objeto

Se você não tiver certeza se PutObject ou MultipartUploader é melhor para a tarefa, use ObjectUploader. O ObjectUploader fará upload de um arquivo grande no Amazon S3 usando PutObject ou MultipartUploader, dependendo do tamanho da carga útil.

require 'vendor/autoload.php'; use Aws\Exception\MultipartUploadException; use Aws\S3\MultipartUploader; use Aws\S3\ObjectUploader; use Aws\S3\S3Client;

Código de exemplo

// Create an S3Client. $s3Client = new S3Client([ 'profile' => 'default', 'region' => 'us-east-2', 'version' => '2006-03-01' ]); $bucket = 'your-bucket'; $key = 'my-file.zip'; // Use a stream instead of a file path. $source = fopen('/path/to/large/file.zip', 'rb'); $uploader = new ObjectUploader( $s3Client, $bucket, $key, $source ); do { try { $result = $uploader->upload(); if ($result["@metadata"]["statusCode"] == '200') { print('<p>File successfully uploaded to ' . $result["ObjectURL"] . '.</p>'); } print($result); // If the SDK chooses a multipart upload, try again if there is an exception. // Unlike PutObject calls, multipart upload calls are not automatically retried. } catch (MultipartUploadException $e) { rewind($source); $uploader = new MultipartUploader($s3Client, $source, [ 'state' => $e->getState(), ]); } } while (!isset($result)); fclose($source);

Configuração

O construtor do objeto ObjectUploader aceita os seguintes argumentos:

$client

O objeto Aws\ClientInterface a ser usado para executar as transferências. Deve ser uma instância de Aws\S3\S3Client.

$bucket

(string, obrigatório) Nome do bucket para o qual o objeto está sendo enviado.

$key

(string, obrigatório) Chave a ser usada para o objeto que está sendo enviado.

$body

(mixed, obrigatório) Dados do objeto a serem carregados. Pode ser um StreamInterface, um recurso de fluxo de PHP ou uma string de dados a ser carregada.

$acl

(string) Lista de controle de acesso (ACL) a ser definida no objeto que está sendo obtido por upload. Por padrão, os objetos são privados.

$options

Uma matriz associativa de opções de configuração para o multipart upload. As seguintes opções de configuração são válidas:

add_content_md5

(bool) Defina como verdadeiro para calcular automaticamente a soma de verificação MD5 para o upload.

mup_threshold

(int, padrão: int(16777216)) O número de bytes para o tamanho do arquivo. Se o tamanho do arquivo exceder esse limite, será usado um carregamento fracionado.

before_complete

(callable) Retorno de chamada a ser invocado antes da operação CompleteMultipartUpload. O retorno de chamada deve ter uma assinatura de função similar a: function (Aws\Command $command) {...}. Consulte a referência da API CompleteMultipartUpload para saber quais parâmetros você pode adicionar ao objeto CommandInterface.

before_initiate

(callable) Retorno de chamada a ser invocado antes da operação CreateMultipartUpload. O retorno de chamada deve ter uma assinatura de função similar a: function (Aws\Command $command) {...}. O SDK invocará esse retorno de chamada se o tamanho do arquivo exceder o valor de mup_threshold. Consulte a referência da API CreateMultipartUpload para saber quais parâmetros você pode adicionar ao objeto CommandInterface.

before_upload

(callable) Retorno de chamada a ser invocado antes de qualquer operação PutObject ou UploadPart. O retorno de chamada deve ter uma assinatura de função similar a: function (Aws\Command $command) {...}. O SDK invocará esse retorno de chamada se o tamanho do arquivo for inferior ou igual ao valor de mup_threshold. Consulte a referência da API PutObject para saber quais parâmetros você pode aplicar à solicitação PutObject. Para os parâmetros que se aplicam a uma solicitação UploadPart, consulte a referência da API UploadPart. O SDK ignora qualquer parâmetro que não seja aplicável à operação representada pelo objeto CommandInterface.

concurrency

(int, padrão: int(3)) O número máximo de operações UploadPart simultâneas permitidas durante o multipart upload.

part_size

(int, padrão: int(5242880)) Tamanho da parte, em bytes, a ser usado ao fazer um multipart upload. Esse valor deve ser de 5 MB a 5 GB, inclusive.

state

(Aws\Multipart\UploadState) Um objeto que representa o estado do multipart upload e que é usado para retomar um upload anterior. Quando essa opção for fornecida, os argumentos $bucket e $key e a opção part_size serão ignoradas.

params

Uma matriz associativa que fornece opções de configuração para cada subcomando. Por exemplo:

new ObjectUploader($bucket, $key, $body, $acl, ['params' => ['CacheControl' => <some_value>])

MultipartUploader

Os multipart uploads são projetados para melhorar a experiência de upload de objetos maiores. Eles permitem fazer upload de objetos em partes independentemente, em qualquer ordem e em paralelo.

Os clientes do Amazon S3 são incentivados a usar os carregamentos fracionados para objetos maiores que 100 MB.

Objeto MultipartUploader

O SDK tem um objeto MultipartUploader especial que simplifica o processo de multipart upload.

Importações

require 'vendor/autoload.php'; use Aws\Exception\MultipartUploadException; use Aws\S3\MultipartUploader; use Aws\S3\S3Client;

Código de exemplo

$s3Client = new S3Client([ 'profile' => 'default', 'region' => 'us-west-2', 'version' => '2006-03-01' ]); // Use multipart upload $source = '/path/to/large/file.zip'; $uploader = new MultipartUploader($s3Client, $source, [ 'bucket' => 'your-bucket', 'key' => 'my-file.zip', ]); try { $result = $uploader->upload(); echo "Upload complete: {$result['ObjectURL']}\n"; } catch (MultipartUploadException $e) { echo $e->getMessage() . "\n"; }

O carregador cria um gerador de dados da parte, com base na origem fornecida e na configuração e tenta fazer upload de todas as partes. Se houver falha em alguma parte do upload, o uploader continuará a fazer upload das partes até que todos os dados de origem tenham sido lidos. Posteriormente, o uploader tentará novamente fazer upload das partes com falha ou lançará uma exceção que contém informações sobre as partes com falha de upload.

Personalização de um carregamento fracionado

Você pode definir opções personalizadas nas operações CreateMultipartUpload, UploadPart e CompleteMultipartUpload executadas pelo multipart uploader por meio de retornos de chamada passados para o construtor.

Importações

require 'vendor/autoload.php'; use Aws\S3\MultipartUploader; use Aws\S3\S3Client;

Código de exemplo

// Create an S3Client $s3Client = new S3Client([ 'profile' => 'default', 'region' => 'us-west-2', 'version' => '2006-03-01' ]); // Customizing a multipart upload $source = '/path/to/large/file.zip'; $uploader = new MultipartUploader($s3Client, $source, [ 'bucket' => 'your-bucket', 'key' => 'my-file.zip', 'before_initiate' => function (Command $command) { // $command is a CreateMultipartUpload operation $command['CacheControl'] = 'max-age=3600'; }, 'before_upload' => function (Command $command) { // $command is an UploadPart operation $command['RequestPayer'] = 'requester'; }, 'before_complete' => function (Command $command) { // $command is a CompleteMultipartUpload operation $command['RequestPayer'] = 'requester'; }, ]);

Coleta de resíduos manual entre carregamentos de partes

Se você atingir o limite de memória com grandes uploads, isso pode ser devido a referências cíclicas geradas pelo SDK ainda não terem sido coletadas pelo coletor de lixo do PHP quando o limite de memória foi atingido. Invocar manualmente o algoritmo de coleta entre operações pode permitir que os ciclos sejam coletados antes que esse limite seja atingido. O exemplo a seguir que invoca o algoritmo de coleta usando um retorno de chamada antes de fazer upload de cada parte. Observe que a invocação do coletor de lixo não vêm com um custo de desempenho e o uso ideal dependerá do seu caso de uso e do ambiente.

$uploader = new MultipartUploader($client, $source, [ 'bucket' => 'your-bucket', 'key' => 'your-key', 'before_upload' => function(\Aws\Command $command) { gc_collect_cycles(); } ]);

Recuperação de erros

Quando ocorre um erro durante o processo de multipart upload, é lançada uma MultipartUploadException. Essa exceção fornece acesso ao objeto UploadState, que contém informações sobre o andamento do multipart upload. O UploadState pode ser usado para retomar um upload que não foi concluído.

Importações

require 'vendor/autoload.php'; use Aws\Exception\MultipartUploadException; use Aws\S3\MultipartUploader; use Aws\S3\S3Client;

Código de exemplo

// Create an S3Client $s3Client = new S3Client([ 'profile' => 'default', 'region' => 'us-west-2', 'version' => '2006-03-01' ]); $source = '/path/to/large/file.zip'; $uploader = new MultipartUploader($s3Client, $source, [ 'bucket' => 'your-bucket', 'key' => 'my-file.zip', ]); //Recover from errors do { try { $result = $uploader->upload(); } catch (MultipartUploadException $e) { $uploader = new MultipartUploader($s3Client, $source, [ 'state' => $e->getState(), ]); } } while (!isset($result)); //Abort a multipart upload if failed try { $result = $uploader->upload(); } catch (MultipartUploadException $e) { // State contains the "Bucket", "Key", and "UploadId" $params = $e->getState()->getId(); $result = $s3Client->abortMultipartUpload($params); }

A retomada de um upload de um UploadState tenta fazer upload das partes que ainda não foram obtidas por upload. O objeto de estado rastreia a partes ausentes, mesmo que sejam consecutivas. O uploader lê ou procura no arquivo de origem fornecido os intervalos de bytes que pertencem às partes que ainda precisam ser obtidas por upload.

UploadStateOs objetos são serializáveis, portanto, você também pode retomar um upload em um outro processo. Você também pode obter o objeto UploadState, mesmo quando não estiver tratando de uma exceção, chamando $uploader->getState().

Importante

Streams passados como uma origem para um MultipartUploader não são automaticamente retrocedidos antes do upload. Se estiver usando um stream em vez de um caminho de arquivo em um loop semelhante ao exemplo anterior, será necessário redefinir a variável $source dentro do bloco catch.

Importações

require 'vendor/autoload.php'; use Aws\Exception\MultipartUploadException; use Aws\S3\MultipartUploader; use Aws\S3\S3Client;

Código de exemplo

// Create an S3Client $s3Client = new S3Client([ 'profile' => 'default', 'region' => 'us-west-2', 'version' => '2006-03-01' ]); //Using stream instead of file path $source = fopen('/path/to/large/file.zip', 'rb'); $uploader = new MultipartUploader($s3Client, $source, [ 'bucket' => 'your-bucket', 'key' => 'my-file.zip', ]); do { try { $result = $uploader->upload(); } catch (MultipartUploadException $e) { rewind($source); $uploader = new MultipartUploader($s3Client, $source, [ 'state' => $e->getState(), ]); } } while (!isset($result)); fclose($source);

Abortar um multipart upload

Um multipart upload pode ser anulado recuperando o UploadId contido no objeto UploadState e passando-o para abortMultipartUpload.

try { $result = $uploader->upload(); } catch (MultipartUploadException $e) { // State contains the "Bucket", "Key", and "UploadId" $params = $e->getState()->getId(); $result = $s3Client->abortMultipartUpload($params); }

Carregamentos fracionados assíncronos

Chamar upload() no MultipartUploader é uma solicitação de bloqueio. Se estiver trabalhando em um contexto assíncrono, você poderá obter uma promessa para o multipart upload.

require 'vendor/autoload.php'; use Aws\S3\MultipartUploader; use Aws\S3\S3Client;

Código de exemplo

// Create an S3Client $s3Client = new S3Client([ 'profile' => 'default', 'region' => 'us-west-2', 'version' => '2006-03-01' ]); $source = '/path/to/large/file.zip'; $uploader = new MultipartUploader($s3Client, $source, [ 'bucket' => 'your-bucket', 'key' => 'my-file.zip', ]); $promise = $uploader->promise();

Configuração

O construtor do objeto MultipartUploader aceita os seguintes argumentos:

$client

O objeto Aws\ClientInterface a ser usado para executar as transferências. Deve ser uma instância de Aws\S3\S3Client.

$source

A origem dos dados que estão sendo carregados. Isso pode ser um caminho ou um URL (por exemplo, /path/to/file.jpg), um identificador de recurso (por exemplo, fopen('/path/to/file.jpg', 'r)) ou uma instância de um stream PSR-7.

$config

Uma matriz associativa de opções de configuração para o multipart upload.

As seguintes opções de configuração são válidas:

acl

(string) Lista de controle de acesso (ACL) a ser definida no objeto que está sendo obtido por upload. Por padrão, os objetos são privados.

before_complete

(callable) Retorno de chamada a ser invocado antes da operação CompleteMultipartUpload. O retorno de chamada deve ter uma assinatura de função como function (Aws\Command $command) {...}.

before_initiate

(callable) Retorno de chamada a ser invocado antes da operação CreateMultipartUpload. O retorno de chamada deve ter uma assinatura de função como function (Aws\Command $command) {...}.

before_upload

(callable) Retorno de chamada a ser invocado antes de qualquer operação UploadPart. O retorno de chamada deve ter uma assinatura de função como function (Aws\Command $command) {...}.

bucket

(string, obrigatório) Nome do bucket para o qual o objeto está sendo enviado.

concurrency

(int, padrão: int(5)) O número máximo de operações UploadPart simultâneas permitidas durante o multipart upload.

key

(string, obrigatório) Chave a ser usada para o objeto que está sendo enviado.

part_size

(int, padrão: int(5242880)) Tamanho da parte, em bytes, a ser usado ao fazer um multipart upload. Esse tamanho deve ser de 5 MB a 5 GB, inclusive.

state

(Aws\Multipart\UploadState) Um objeto que representa o estado do multipart upload e que é usado para retomar um upload anterior. Quando essa opção for fornecida, as opções bucket, key e part_size serão ignoradas.

add_content_md5

(boolean) Defina como verdadeiro para calcular automaticamente a soma de verificação MD5 para o upload.

params

Uma matriz associativa que fornece opções de configuração para cada subcomando. Por exemplo:

new MultipartUploader($client, $source, ['params' => ['CacheControl' => <some_value>]])

Cópias de várias partes

O AWS SDK para PHP também inclui um objeto MultipartCopy que é usado de maneira semelhante ao MultipartUploader, mas é projetado para copiar objetos entre 5 GB e 5 TB no Amazon S3.

require 'vendor/autoload.php'; use Aws\Exception\MultipartUploadException; use Aws\S3\MultipartCopy; use Aws\S3\S3Client;

Código de exemplo

// Create an S3Client $s3Client = new S3Client([ 'profile' => 'default', 'region' => 'us-west-2', 'version' => '2006-03-01' ]); //Copy objects within S3 $copier = new MultipartCopy($s3Client, '/bucket/key?versionId=foo', [ 'bucket' => 'your-bucket', 'key' => 'my-file.zip', ]); try { $result = $copier->copy(); echo "Copy complete: {$result['ObjectURL']}\n"; } catch (MultipartUploadException $e) { echo $e->getMessage() . "\n"; }