PHP Stream Writer to S3 with Tagging
Published Nov 13, 2024
Reading time 2 minutes
PHP Stream Writer to S3 with a Tag
In an application I work on, we’re using the PHP Stream Writer for writing objects to S3 and we needed to add a tag at the PutObject
stage to trigger S3 object replication. I found documentation on how to format the request a bit thin on the ground.
This is how I formatted the request to tag the object at the time the file was being written which triggered the bucket replication rule on a tag.
class S3StorageAdapter {
public function __construct(S3Client $s3Client, string $bucket)
{
$this->client = $s3Client;
$this->bucket = $bucket;
$this->client->registerStreamWrapper();
}
public function getStreamUrl($filename)
{
return 's3://my-bucket' . DIRECTORY_SEPARATOR . basename($filename);
}
}
In the writer service:
class Writer {
public function write(string $filename, string $data, string $tag) {
$opts = [
's3' => [
'Tagging' => $tag
]
];
$context = stream_context_create($opts);
$handle = fopen($filename, 'w', false, $context);
fputcsv($handle, $data, ',');
fflush($handle);
fclose($handle);
}
}
Write out the file to S3:
$streamUrl = $this->storageAdapter->getStreamUrl($job, false);
$this->writer->write($streamUrl, $data, "myTag=true");
From the PHP code in the S3 Client Interface, it states:
params: (array, default=array([])) Custom parameters to use with the upload. For single uploads, they must correspond to those used for the PutObject operation. For multipart uploads, they correspond to the parameters of the CreateMultipartUpload operation.
I only needed to add a Tag to the PutObject
command, but any other options that are required that are available to the API can be added to the file handle in the same format as shown above.
Did AI Have the Answer
A few days after solving this, I was at an AI away day when I realised it hadn’t occurred to use AI to help find the solution. I asked Amazon’s Q how to tag using PHP stream wrapper SDK and it said it wasn’t possible. ChatGPT also suggested using the putObject
command instead but GitHub Copilot gave an almost working solution.