The official PHP SDK provides an easy way to interact with Bunny Storage in your PHP applications.
Installation
composer require bunnycdn/storage
Quickstart
Connect to your storage zone
use Bunny\Storage\Client;
use Bunny\Storage\Region;
$client = new Client(
'your-access-key',
'your-storage-zone-name',
Region::FALKENSTEIN // Optional: storage zone region
);
Available regions:
| Region Constant | Code | Location | City |
|---|
Region::FALKENSTEIN | de | Frankfurt, DE | Falkenstein (default) |
Region::LONDON | uk | London, UK | London |
Region::STOCKHOLM | se | Stockholm, SE | Stockholm |
Region::NEW_YORK | ny | New York, US | New York |
Region::LOS_ANGELES | la | Los Angeles, US | Los Angeles |
Region::SINGAPORE | sg | Singapore, SG | Singapore |
Region::SYDNEY | syd | Sydney, AU | Sydney |
Region::SAO_PAULO | br | Sao Paulo, BR | Sao Paulo |
Region::JOHANNESBURG | jh | Johannesburg, ZA | Johannesburg |
List files
$files = $client->listFiles('remote/path/');
// Navigate subdirectories
$subfolderFiles = $client->listFiles('my-folder/');
Returns an array of FileInfo objects.
FileInfo properties:
getGuid() - Unique identifier
getName() - File name
getPath() - Directory path
getSize() - File size in bytes
getChecksum() - File checksum
getDateCreated() - Creation date
getDateModified() - Last modification date
isDirectory() - Whether it’s a directory
Upload a file
Single file
Without checksum
Async
String content
$client->upload('/path/to/local/file.txt', 'remote/path/hello-world.txt');
$client->upload('/path/to/local/file.txt', 'remote/path/hello-world.txt', false);
$promise = $client->uploadAsync('/path/to/local/file.txt', 'remote/path/hello-world.txt');
// Returns a GuzzleHttp\Promise\PromiseInterface
$content = 'Hello, world!';
$client->putContents('hello-world.txt', $content);
// Without checksum
$client->putContents('hello-world.txt', $content, false);
Upload multiple files
Batch (sequential)
Async (concurrent)
$files = glob('./uploads/*');
foreach ($files as $file) {
if (is_file($file)) {
$client->upload($file, 'batch/' . basename($file));
}
}
use GuzzleHttp\Promise\Utils;
$files = [
'/path/to/file1.jpg' => 'uploads/file1.jpg',
'/path/to/file2.jpg' => 'uploads/file2.jpg',
'/path/to/file3.jpg' => 'uploads/file3.jpg',
];
$promises = [];
foreach ($files as $localPath => $remotePath) {
$promises[$remotePath] = $client->uploadAsync($localPath, $remotePath);
}
$results = Utils::settle($promises)->wait();
Download a file
$client->download('remote/path/hello-world.txt', '/path/to/local/file.txt');
$content = $client->getContents('hello-world.txt');
echo $content; // Hello, world!
Get file info
$fileInfo = $client->info('remote/path/hello-world.txt');
echo $fileInfo->getName();
echo $fileInfo->getSize();
echo $fileInfo->getChecksum();
Check if file exists
if ($client->exists('remote/path/hello-world.txt')) {
echo 'File exists!';
}
Delete a file
$client->delete('remote/path/hello-world.txt');
// Delete a directory
$client->delete('remote/path/folder/');
Delete multiple files
$errors = $client->deleteMultiple(['file1.txt', 'file2.txt', 'non-existing.txt']);
// Returns array of errors for failed deletions
// ['non-existing.txt' => 'Object not found']
Examples
Explore complete working examples in the GitHub repository:
| Example | Description |
|---|
| file-upload | Upload a single file to storage |
| batch-upload | Upload multiple files sequentially |
| async-upload | Upload multiple files concurrently using promises |
| form-upload | Handle file uploads from HTML forms |
| list-files | List all files in a directory |
| download-file | Download a file from storage |
| file-info | Retrieve file metadata |
| delete-file | Delete a single file |
| delete-multiple-files | Delete multiple files in one operation |
| delete-old-files | Find and delete files older than a specified age |
| kitchen-sink | Complete UI with upload, list, view, and delete |
Resources
Last modified on November 25, 2025