A Flysystem adapter for storing files in a database using PDO
- Uses multiple tables.
- Stores files in chunks.
- Option to compress the file when stored.
This implementation is optimised for use with large files when using the streams. It avoids loading the complete file into memory, preferring to store files during operation on the local file system.
use Phlib\Flysystem\Pdo\PdoAdapter; use League\Flysystem\Filesystem; $pdo = new \PDO('mysql:host=hostname;dbname=database_name', 'username', 'password'); $adapter = new PdoAdapter($pdo); $filesystem = new Filesystem($adapter);
use League\Flysystem\Config; $config = new Config([ 'enable_compression' => false, 'visibility' => AdapterInterface::VISIBILITY_PUBLIC ]); $adapter->writeStream('/path/to/file.zip', $handle, $config);
||Prepends all tablenames.|
||Compresses a file stored in DB.|
||Changes the size of file chunks stored in bytes. Defaults to 1MB.|
||Location to store temporary files when they're stored and retrieved.|
||Stops large file results being pulled into memory|
use League\Flysystem\Config; $config = new Config([ 'table_prefix' => 'flysystem', 'enable_compression' => true, 'chunk_size' => 1048576, 'temp_dir' => '/var/tmp', 'disable_mysql_buffering' => true ]); $adapter = new PdoAdapter($pdo, $config);
The following file configurations were added in version 1.1. These configurations and associated schema changes are optional.
|expiry||string||Specify a expiry time for the file|
|meta||mixed||Any additional information. Uses JSON encoding to store the information|
By specifying 'expiry' as a configuration parameter when writing or updating a file the
will store the value in a column called 'expiry'. When the information about the file is selected out, if the expiry
exists and can be parsed by
strtotime, then the expiry time will be evaluated. False is returned if the file doesn't
exist or has expired.
The schema for the expiry column can be anything that stores a value that will be evaluated by
this will be a
timestamp column type.
$config = new Config(['expiry' => date('Y-m-d H:i:s', strtotime('+2 days'))]); $adapter->write($path, $content, $config);
The expiry is now part of the file description.
$data = $adapter->getMetadata($path); [ 'path' => '...', '...', 'expiry' => '' ]
It's possible to store additional meta data about a file or directory. This could include owner, permissions or groups for example. The information is stored as a JSON encoded string in whatever form you provide. One the item is retrieved from the Filesystem the additional meta information is provided in the same format it was originally provided.
$config = new Config(['meta' => ['owner' => 'John Smith', 'permissions' => 600]]); $adapter->write($path, $content, $config);
Those details are now part of the file description.
$data = $adapter->getMetadata($path); [ 'path' => '...', '...', 'meta' => [ 'owner' => 'John Smith', 'permissions' => 600 ] ]
Schemas can be found in the schema directory. Specific types can be changed based on requirements. All field names should remain the same. Notes about the DB specific definitions are below.
pathcolumn is set to allow up to 255 characters.
sizecolumn has been set to a unsigned
INTtype to allow for convenient searching. This allows up to 4G files to be recorded. This can be changed to a
VARCHARif searching is not required.
- The size of chunks, allows for up to 16M per chunk.
Any use of
update with large files will cause problems with memory usage. The associated stream
methods have been optimised to use as little memory as possible. The adapter first saves the file to the local
filesystem before transferring it to the database.
On MySQL, the default behaviour is to buffer all query results. When reading a file back from the database this could cause memory problems. There is a configuration option which disables the buffering. This has the side effect that the pdo connection specified in the constructor is altered to set this attribute.
Compression is especially useful when storing text based files. The compression option defaults to on. The side effect of this is that when reading files back some files may cause larger than expected memory usage. As an example, a very large file filled with a single letter 'a', can be compressed to a tiny size. When that file is read, the tiny chunk is expanded and will fill the memory.
When a file is stored, the setting for compression is stored with it. This can not be changed.
Chunking has been implemented to aid where systems have been set up for replication. Packet sizes are a consideration here.
This package is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this program. If not, see http://www.gnu.org/licenses/.