BunnyCDN via FlySystem on Symfony
You can comment on this post on my Mastodon post for "BunnyCDN via FlySystem on Symfony"
I've been refactoring the code at work to help move uploaded files off the main server, and also optimise the images when they are used (no need to use a 4000 x 3000px 4.7MB file for a 500px wide thumbnail!). The standard library to upload files to a remote filesystem with PHP is FlySystem, it's been been easy to work with - even if it's not (yet) using Symfony on this project.
We are using BunnyCDN for the new storage and CDN, and it looks to be excellent value, useful add-ins (for image resizing and optimisation), and most of all, PHP support - something that the site's usual hosting platform, Azure, is not apparently not willing to provide, with a PHP SDK to talk to the relevant services.
I was curious though - how easy would it be to add Bunny into a Symfony-based project, since it doesn't come included as a first-class storage adaptor in the flysystem-bundle.
Turns out - quite easily, since the adapter can be either one of the list of built-in adapters, or the name of a service where you've created a fully-configured adapter yourself.
1# config/packages/flysystem.yaml:
2# Read the documentation at https://github.com/thephpleague/flysystem-bundle/blob/master/docs/1-getting-started.md
3flysystem:
4 storages:
5 local.storage:
6 adapter: 'local'
7 options:
8 directory: '%kernel.project_dir%/storage/default'
9
10 uploads.storage:
11 adapter: 'flySystem.uploads.adaptor'
There is also a couple of other options available to add here - public_url_generator
& temporary_url_generator
that refer to other pre-created, named services.
Here's how a custom-adaptor can be created, in config/services.yaml
:
1services:
2 flySystem.uploads.client:
3 class: PlatformCommunity\Flysystem\BunnyCDN\BunnyCDNClient
4 arguments:
5 $storage_zone_name: 'zone-name'
6 $api_key: 'api_key......'
7 $region: 'uk'
8 flySystem.uploads.adaptor:
9 class: PlatformCommunity\Flysystem\BunnyCDN\BunnyCDNAdapter
10 arguments:
11 $client: '@flySystem.uploads.client'
12 $pullzone_url: 'https://uploads.example.com'
Normally, the details for the BunnyCDNClient
, and $pullzone_url
in the BunnyCDNAdapter
will come from an enviroment variable (and possibly decoded from a URL-like DSN).
And finally, the system can be used by typhinting FilesystemOperator
& giving the name - here, uploads.storage
converts to $uploadsStorage
, and the argument is ready to use, for reading and writing files to the Bunny storage zone, and then via the CDN/pull-zone for general use.
1<?php
2// src/Controller/FlySystemExampleController.php:
3namespace App\Controller;
4// use ...
5
6#[Route('/example/fly')]
7class FlySystemExampleController extends AbstractController
8{
9 public function __invoke(private FilesystemOperator $uploadsStorage) {
10 dd($uploadsStorage);
11 }
12}
To get the other version of the FlySystem Filesystem that was configured in flysystem.yaml, just name it when you typehint the class:
1 public function __invoke(private FilesystemOperator $localStorage) {
2 dd($localStorage);
3 }