Drivers
S3 Compatible Object Storage Driver
Using the Object Storage Driver to connect to S3 compatible Storage.
Introduction
The S3 Driver provides a seamless interface for interacting with AWS S3 and S3-compatible object storage providers (such as DigitalOcean Spaces, MinIO, UpCloud, Hetzner or custom solutions like Ceph). It supports multiple simultaneous connections, allowing you to manage buckets across different regions or providers within a single application.
Key features include:
- Multi-Connection Support: Configure and switch between multiple storage endpoints (e.g.,
default,asia,archive) easily. - S3 Compatibility: Works with any S3-compliant API by allowing custom endpoints, regions, path-style addressing and non-chunked uploads.
- Tunable Uploads: A per-connection default multipart part size, overridable per upload.
- Environment-Driven: Credentials and endpoints are managed via environment variables for security.
Installation
Install the driver via composer by running:
composer require kipchak/driver-s3
Initialise the Driver
Add the following line to your drivers/drivers.php file:
\Kipchak\Driver\S3\S3::initialise($container);
Configuration
The configuration in kipchak.s3.php can be used to configure multiple storage connections:
Connection Settings
For each named connection, you can define:
access_key: The API Access Key ID.secret_key: The API Secret Access Key.region: The geographical region of the bucket (e.g.,us-east-1,sg).endpoint: The base URL of the S3 service. This is critical for non-AWS providers.
Three further settings are optional, for providers that deviate from AWS behaviour and for tuning uploads:
path_style(bool, defaultfalse): Use path-style addressing (https://endpoint/bucket/key) instead of virtual-hosted addressing (https://bucket.endpoint/key). Required by MinIO and recommended for Ceph-backed providers such as Hetzner Object Storage, where per-bucket DNS may not exist.send_chunked_body(bool, defaulttrue): Whether uploads are streamed with aws-chunked content encoding. Disable this for providers that do not support it (e.g. Google Cloud Storage in interoperability mode).part_size(int, default64): Megabytes per part for multipartupload(). Must be a power of 2, max 4096. S3 allows at most 10,000 parts per object, so the default supports objects up to 640GB — raise it (128, 256, 512…) if you upload larger objects. Individualupload()calls can override it via['PartSize' => 128].
Example Configuration
<?php
use function Kipchak\Core\env;
return [
// Primary storage connection
'default' => [
'access_key' => env('S3_ACCESS_KEY', ''),
'secret_key' => env('S3_SECRET_KEY', ''),
'region' => 'sg',
'endpoint' => 'https://sg.objects.mamluk.net'
],
// Secondary storage connection (e.g., different region)
'asia' => [
'access_key' => env('ASIA_ACCESS_KEY', ''),
'secret_key' => env('ASIA_SECRET_KEY', ''),
'region' => 'ap-central-1',
'endpoint' => 'https://ap.objects.mamluk.net'
],
// An S3-compatible provider needing path-style addressing and larger parts
'hetzner' => [
'access_key' => env('HETZNER_ACCESS_KEY', ''),
'secret_key' => env('HETZNER_SECRET_KEY', ''),
'region' => 'fsn1',
'endpoint' => 'https://fsn1.your-objectstorage.com',
'path_style' => true,
'part_size' => 128,
],
];
Please see the configuration file in the starter project at https://1x.ax/mamluk/kipchak/starter/~files/master/config/kipchak.s3.php for full configuration details.
Usage
Environment Variables
Ensure your .env file contains the credentials referenced in your config:
S3_ACCESS_KEY=my-access-key
S3_SECRET_KEY=my-secret-key
ASIA_ACCESS_KEY=another-access-key
ASIA_SECRET_KEY=another-secret-key
Code Example
The driver allows you to select a specific connection using the configuration keys defined above. If no connection is specified, it defaults to the default key.
<?php
// 1. Initialize the client
$s3 = \Kipchak\Driver\S3\S3::get('default'); // default is the connection name in the config file.
// 2. Get all buckets in the 'default' connection
foreach ($s3->listBuckets() as $bucket) {
echo $bucket->getName();
}
// 3. Upload a file to a bucket in the 'default' connection
$s3->upload('bucket-name', 'avatars/user_1.jpg', file_get_contents('/tmp/image.jpg'));
// 4. Upload with an explicit multipart part size (in MB), overriding the
// connection's part_size for this call only
$s3->upload('bucket-name', 'backups/db.sql.gz', fopen('/tmp/db.sql.gz', 'rb'), ['PartSize' => 256]);
The client returned by the driver extends AsyncAws' SimpleS3Client, so everything documented at https://async-aws.com/integration/simple-s3.html and https://async-aws.com/clients/s3.html is available on it.
Git Repository
The source code for this driver is available on 1x.ax at https://1x.ax/mamluk/kipchak/drivers/s3.