

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Objets de commande dans la AWS SDK pour PHP version 3
<a name="guide_commands"></a>

 AWS SDK pour PHP Utilise le [modèle de commande](http://en.wikipedia.org/wiki/Command_pattern) pour encapsuler les paramètres et le gestionnaire qui seront utilisés pour transférer une requête HTTP ultérieurement.

## Utilisation implicite de commandes
<a name="implicit-use-of-commands"></a>

Si vous examinez une classe client, vous constaterez que les méthodes correspondant aux opérations d'API n'existent pas réellement. Elles sont implémentées à l'aide de la méthode magique `__call()`. Ces pseudo-méthodes sont en réalité des raccourcis qui encapsulent l'utilisation des objets de commande par le kit SDK.

Vous n'avez généralement pas besoin d'interagir directement avec les objets de commande. Lorsque vous appelez des méthodes telles que `Aws\S3\S3Client::putObject()`, le kit SDK crée un objet `Aws\CommandInterface` en fonction des paramètres fournis, exécute la commande et renvoie un objet `Aws\ResultInterface` renseigné (ou lève une exception en cas d'erreur). Un flux similaire se produit lorsqu'une des méthodes `Async` d'un client (par exemple, `Aws\S3\S3Client::putObjectAsync()`) est appelée : le client crée une commande en fonction des paramètres fournis, sérialise une demande HTTP, initie la demande et renvoie une promesse.

Les exemples suivants sont équivalents d'un point de vue fonctionnel.

```
$s3Client = new Aws\S3\S3Client([
    'version' => '2006-03-01',
    'region'  => 'us-standard'
]);

$params = [
    'Bucket' => 'amzn-s3-demo-bucket',
    'Key'    => 'baz',
    'Body'   => 'bar'
];

// Using operation methods creates a command implicitly
$result = $s3Client->putObject($params);

// Using commands explicitly
$command = $s3Client->getCommand('PutObject', $params);
$result = $s3Client->execute($command);
```

## Paramètres de commande
<a name="command-parameters"></a>

Toutes les commandes prennent en charge un certain nombre de paramètres spéciaux qui ne font pas partie de l'API d'un service, mais contrôlent le comportement du kit SDK.

### `@http`
<a name="http"></a>

Vous pouvez, à l'aide de ce paramètre, ajuster la manière dont le gestionnaire HTTP sous-jacent exécute la demande. Vous pouvez inclure dans le paramètre `@http` les mêmes options que celles définies lors de l'instanciation du client à l'aide de l'[option client « http »](guide_configuration.md#config-http).

```
// Configures the command to be delayed by 500 milliseconds
$command['@http'] = [
    'delay' => 500,
];
```

### `@retries`
<a name="retries"></a>

Comme l'[option client « retries »](guide_configuration.md#config-retries), `@retries` (nouvelles tentatives) contrôle le nombre de fois où une commande peut être relancée avant que celle-ci ne soit considérée comme ayant échoué. Définissez-la sur `0` pour désactiver les nouvelles tentatives.

```
// Disable retries
$command['@retries'] = 0;
```

**Note**  
Si vous avez désactivé les nouvelles tentatives sur un client, vous ne pouvez pas les activer de manière sélective sur des commandes individuelles transmises à ce client.

## Création d'objets de commande
<a name="creating-command-objects"></a>

Vous pouvez créer une commande à l'aide de la méthode `getCommand()` d'un client. Une demande HTTP ne sera pas immédiatement exécutée ou transférée. L'exécution de la demande ne sera effectuée qu'une fois la commande transmise à la méthode `execute()` du client. Vous avez ainsi la possibilité de modifier l'objet de commande avant d'exécuter la commande.

```
$command = $s3Client->getCommand('ListObjects');
$command['MaxKeys'] = 50;
$command['Prefix'] = 'foo/baz/';
$result = $s3Client->execute($command);

// You can also modify parameters
$command = $s3Client->getCommand('ListObjects', [
    'MaxKeys' => 50,
    'Prefix'  => 'foo/baz/',
]);
$command['MaxKeys'] = 100;
$result = $s3Client->execute($command);
```

## Commande `HandlerList`
<a name="command-handlerlist"></a>

Lorsqu'une commande est créée à partir d'un client, elle reçoit un clone de l'objet `Aws\HandlerList` du client. La commande reçoit un **clone** de la liste des gestionnaires du client pour autoriser une commande à utiliser un intergiciel et des gestionnaires personnalisés qui n'affectent pas les autres commandes exécutées par le client.

Cela signifie que vous pouvez utiliser un client HTTP différent par commande (par exemple, `Aws\MockHandler`) et ajouter un comportement personnalisé par commande via l'intergiciel. L'exemple suivant utilise un `MockHandler` pour créer des résultats fictifs au lieu d'envoyer des demandes HTTP réelles.

```
use Aws\Result;
use Aws\MockHandler;

// Create a mock handler
$mock = new MockHandler();
// Enqueue a mock result to the handler
$mock->append(new Result(['foo' => 'bar']));
// Create a "ListObjects" command
$command = $s3Client->getCommand('ListObjects');
// Associate the mock handler with the command
$command->getHandlerList()->setHandler($mock);
// Executing the command will use the mock handler, which returns the
// mocked result object
$result = $client->execute($command);

echo $result['foo']; // Outputs 'bar'
```

En plus de changer le gestionnaire utilisé par la commande, vous pouvez également injecter un intergiciel personnalisé dans la commande. L'exemple suivant utilise l'intergiciel `tap`, qui fonctionne comme observateur dans la liste des gestionnaires.

```
use Aws\CommandInterface;
use Aws\Middleware;
use Psr\Http\Message\RequestInterface;

$command = $s3Client->getCommand('ListObjects');
$list = $command->getHandlerList();

// Create a middleware that just dumps the command and request that is
// about to be sent
$middleware = Middleware::tap(
    function (CommandInterface $command, RequestInterface $request) {
        var_dump($command->toArray());
        var_dump($request);
    }
);

// Append the middleware to the "sign" step of the handler list. The sign
// step is the last step before transferring an HTTP request.
$list->append('sign', $middleware);

// Now transfer the command and see the var_dump data
$s3Client->execute($command);
```

## `CommandPool`
<a name="command-pool"></a>

Le `Aws\CommandPool` vous permet d'exécuter des commandes simultanément à l'aide d'un itérateur générant des objets `Aws\CommandInterface`. Le `CommandPool` veille à ce qu'un nombre constant de commandes soient exécutées simultanément pendant l'itération sur les commandes du groupe (à mesure que les commandes se terminent, d'autres sont exécutées pour garantir une taille de groupe constante).

Voici un exemple très simple illustrant l'envoi de quelques commandes à l'aide d'un `CommandPool`.

```
use Aws\S3\S3Client;
use Aws\CommandPool;

// Create the client
$client = new S3Client([
    'region'  => 'us-standard',
    'version' => '2006-03-01'
]);

$bucket = 'amzn-s3-demo-bucket';
$commands = [
    $client->getCommand('HeadObject', ['Bucket' => $bucket, 'Key' => 'a']),
    $client->getCommand('HeadObject', ['Bucket' => $bucket, 'Key' => 'b']),
    $client->getCommand('HeadObject', ['Bucket' => $bucket, 'Key' => 'c'])
];

$pool = new CommandPool($client, $commands);

// Initiate the pool transfers
$promise = $pool->promise();

// Force the pool to complete synchronously
$promise->wait();
```

Cet exemple est relativement peu puissant pour le `CommandPool`. Essayons un exemple plus complexe. Supposons que vous souhaitiez télécharger des fichiers sur disque dans un compartiment Amazon S3. Pour obtenir une liste des fichiers à partir du disque, nous pouvons utiliser le `DirectoryIterator` de PHP. Cet itérateur génère des objets `SplFileInfo`. Le `CommandPool` accepte un itérateur générant des objets `Aws\CommandInterface`. Nous devons donc mapper les objets `SplFileInfo` pour renvoyer des objets `Aws\CommandInterface`.

```
<?php
require 'vendor/autoload.php';

use Aws\Exception\AwsException;
use Aws\S3\S3Client;
use Aws\CommandPool;
use Aws\CommandInterface;
use Aws\ResultInterface;
use GuzzleHttp\Promise\PromiseInterface;

// Create the client
$client = new S3Client([
    'region'  => 'us-standard',
    'version' => '2006-03-01'
]);

$fromDir = '/path/to/dir';
$toBucket = 'amzn-s3-demo-bucket';

// Create an iterator that yields files from a directory
$files = new DirectoryIterator($fromDir);

// Create a generator that converts the SplFileInfo objects into
// Aws\CommandInterface objects. This generator accepts the iterator that
// yields files and the name of the bucket to upload the files to.
$commandGenerator = function (\Iterator $files, $bucket) use ($client) {
    foreach ($files as $file) {
        // Skip "." and ".." files
        if ($file->isDot()) {
            continue;
        }
        $filename = $file->getPath() . '/' . $file->getFilename();
        // Yield a command that is executed by the pool
        yield $client->getCommand('PutObject', [
            'Bucket' => $bucket,
            'Key'    => $file->getBaseName(),
            'Body'   => fopen($filename, 'r')
        ]);
    }
};

// Now create the generator using the files iterator
$commands = $commandGenerator($files, $toBucket);

// Create a pool and provide an optional array of configuration
$pool = new CommandPool($client, $commands, [
    // Only send 5 files at a time (this is set to 25 by default)
    'concurrency' => 5,
    // Invoke this function before executing each command
    'before' => function (CommandInterface $cmd, $iterKey) {
        echo "About to send {$iterKey}: "
            . print_r($cmd->toArray(), true) . "\n";
    },
    // Invoke this function for each successful transfer
    'fulfilled' => function (
        ResultInterface $result,
        $iterKey,
        PromiseInterface $aggregatePromise
    ) {
        echo "Completed {$iterKey}: {$result}\n";
    },
    // Invoke this function for each failed transfer
    'rejected' => function (
        AwsException $reason,
        $iterKey,
        PromiseInterface $aggregatePromise
    ) {
        echo "Failed {$iterKey}: {$reason}\n";
    },
]);

// Initiate the pool transfers
$promise = $pool->promise();

// Force the pool to complete synchronously
$promise->wait();

// Or you can chain the calls off of the pool
$promise->then(function() { echo "Done\n"; });
```

### Configuration de l’`CommandPool`
<a name="commandpool-configuration"></a>

Le constructeur `Aws\CommandPool` accepte différentes options de configuration.

**concurrency (callable\$1int)**  
Nombre maximal de commandes pouvant être exécutées simultanément. Fournissez une fonction pour redimensionner le groupe de manière dynamique. La fonction reçoit le nombre actuel de demandes en attente et devrait renvoyer un nombre entier représentant la nouvelle limite de taille du groupe.

**before (callable)**  
Fonction à appeler avant d'envoyer chaque commande. La fonction `before` accepte la commande et la clé de l'itérateur de la commande. Vous pouvez muter la commande, si nécessaire, dans la fonction `before` avant d'envoyer la commande.

**fulfilled (callable)**  
Fonction à appeler lorsqu'une promesse est exécutée. La fonction reçoit l'objet de résultat, l'ID de l'itérateur à partir duquel provient le résultat et la promesse agrégée pouvant être résolue ou rejetée si vous devez court-circuiter le groupe.

**rejected (callable)**  
Fonction à appeler lorsqu'une promesse est rejetée. La fonction reçoit un objet `Aws\Exception`, l'ID de l'itérateur à partir duquel provient l'exception et la promesse agrégée pouvant être résolue ou rejetée si vous devez court-circuiter le groupe.

### Collecte manuelle des déchets entre les commandes
<a name="manual-garbage-collection-between-commands"></a>

Si vous atteignez la limite de mémoire lors de groupes de commandes volumineux, c'est peut-être parce que des références cycliques générées par le kit SDK n'ont pas encore été traitées par le [nettoyage de mémoire de PHP](https://www.php.net/manual/en/features.gc.php). L'appel manuel de l'algorithme de nettoyage entre les commandes peut permettre le traitement des cycles avant que cette limite ne soit atteinte. L'exemple suivant crée un `CommandPool` qui appelle l'algorithme de nettoyage en utilisant un rappel avant l'envoi de chaque commande. Notez que l'appel du nettoyage de mémoire représente un coût en termes de performances, et que l'utilisation optimale dépendra de votre cas d'utilisation et de l'environnement.

```
$pool = new CommandPool($client, $commands, [
    'concurrency' => 25,
    'before' => function (CommandInterface $cmd, $iterKey) {
        gc_collect_cycles();
    }
]);
```