10 KiB
File system
The file system component integrates the famous League\Flysystem
in the PHP ecosystem (this is also the underlying library of many well-known frameworks such as Laravel). Through reasonable abstraction, the program does not have to perceive whether the storage engine is a local hard disk or a cloud server, realizing decoupling. This component provides coroutine support for common cloud storage services.
Install
composer require hyperf/filesystem
The versions of League\Flysystem
components v1.0
, v2.0
and v3.0
have changed greatly, so you need to install the corresponding adapters according to different versions
- Alibaba Cloud OSS adapter
Flysystem v1.0
version
composer require xxtime/flysystem-aliyun-oss
Flysystem v2.0
and Flysystem v3.0
versions
composer require hyperf/flysystem-oss
- S3 adapter
Flysystem v1.0
version
composer require "league/flysystem-aws-s3-v3:^1.0"
composer require hyperf/guzzle
Flysystem v2.0
version
composer require "league/flysystem-aws-s3-v3:^2.0"
composer require hyperf/guzzle
- Qiniu Adapter
Flysystem v1.0
version
composer require "overtrue/flysystem-qiniu:^1.0"
Flysystem v2.0
version
composer require "overtrue/flysystem-qiniu:^2.0"
Flysystem v3.0
version
composer require "overtrue/flysystem-qiniu:^3.0"
- memory adapter
Flysystem v1.0
version
composer require "league/flysystem-memory:^1.0"
Flysystem v2.0
version
composer require "league/flysystem-memory:^2.0"
- Tencent Cloud COS Adapter
Flysystem v1.0
version
flysystem-cos v2.0 version is deprecated, please modify it to 3.0 version according to the latest documentation
composer require "overtrue/flysystem-cos:^3.0"
Flysystem v2.0
version
composer require "overtrue/flysystem-cos:^4.0"
Flysystem v3.0
version
composer require "overtrue/flysystem-cos:^5.0"
After the installation is complete, execute
php bin/hyperf.php vendor:publish hyperf/filesystem
The config/autoload/file.php
file will be generated. Set the default driver in this file, and configure the access key, access secret and other information of the corresponding driver, and you can use it.
use
It can be used by injecting League\Flysystem\Filesystem
through DI.
The API is as follows:
The following example is Flysystem v1.0 version, please refer to the official documentation for v2.0 version
<?php
declare(strict_types=1);
namespace App\Controller;
class IndexController extends AbstractController
{
public function example(\League\Flysystem\Filesystem $filesystem)
{
// Process Upload
$file = $this->request->file('upload');
$stream = fopen($file->getRealPath(), 'r+');
$filesystem->writeStream(
'uploads/'.$file->getClientFilename(),
$stream
);
fclose($stream);
// Write Files
$filesystem->write('path/to/file.txt', 'contents');
// Add local file
$stream = fopen('local/path/to/file.txt', 'r+');
$result = $filesystem->writeStream('path/to/file.txt', $stream);
if (is_resource($stream)) {
fclose($stream);
}
// Update Files
$filesystem->update('path/to/file.txt', 'new contents');
// Check if a file exists
$exists = $filesystem->has('path/to/file.txt');
// Read Files
$contents = $filesystem->read('path/to/file.txt');
// Delete Files
$filesystem->delete('path/to/file.txt');
// Rename Files
$filesystem->rename('filename.txt', 'newname.txt');
// Copy Files
$filesystem->copy('filename.txt', 'duplicate.txt');
// list the contents
$filesystem->listContents('path', false);
}
}
At some point, you will need to use multiple storage media at the same time. At this point, you can inject Hyperf\Filesystem\FilesystemFactory
to dynamically choose which driver to use.
<?php
declare(strict_types=1);
namespace App\Controller;
class IndexController
{
public function example(\Hyperf\Filesystem\FilesystemFactory $factory)
{
$local = $factory->get('local');
// Write Files
$local->write('path/to/file.txt', 'contents');
$s3 = $factory->get('s3');
$s3->write('path/to/file.txt', 'contents');
}
}
Configure static resources
If you want to access files uploaded locally via http, please add the following configuration to the config/autoload/server.php
configuration.
return [
'settings' => [
...
// Replace public with the upload directory
'document_root' => BASE_PATH . '/public',
'enable_static_handler' => true,
],
];
Precautions
- Please make sure to install the
hyperf/guzzle
component for S3 storage to provide coroutine support. For Alibaba Cloud, Qiniu Cloud, and Tencent Cloud, please Open Curl Hook to use coroutines. Due to the parameter support of Curl Hook, please use Swoole 4.4.13 or later. - Private object storage solutions such as minIO and ceph radosgw all support the S3 protocol and can use the S3 adapter.
- When using the Local driver, the root directory is the configured address, not the root directory of the operating system. For example, if the local driver
root
is set to/var/www
, then/var/www/public/file.txt
on the local disk should be accessed through the flysystem API using/public/file.txt
orpublic/file.txt
. - Taking Alibaba Cloud OSS as an example, the read operation performance comparison of 1 core and 1 process:
ab -k -c 10 -n 1000 http://127.0.0.1:9501/
CURL HOOK is not enabled:
Concurrency Level: 10
Time taken for tests: 202.902 seconds
Complete requests: 1000
Failed requests: 0
Keep-Alive requests: 1000
Total transferred: 146000 bytes
HTML transferred: 5000 bytes
Requests per second: 4.93 [#/sec] (mean)
Time per request: 2029.016 [ms] (mean)
Time per request: 202.902 [ms] (mean, across all concurrent requests)
Transfer rate: 0.70 [Kbytes/sec] received
After enabling CURL HOOK:
Concurrency Level: 10
Time taken for tests: 9.252 seconds
Complete requests: 1000
Failed requests: 0
Keep-Alive requests: 1000
Total transferred: 146000 bytes
HTML transferred: 5000 bytes
Requests per second: 108.09 [#/sec] (mean)
Time per request: 92.515 [ms] (mean)
Time per request: 9.252 [ms] (mean, across all concurrent requests)
Transfer rate: 15.41 [Kbytes/sec] received
Detailed configuration
return [
// Select the key corresponding to the driver under storage.
'default' => 'local',
'storage' => [
'local' => [
'driver' => \Hyperf\Filesystem\Adapter\LocalAdapterFactory::class,
'root' => __DIR__ . '/../../runtime',
],
'ftp' => [
'driver' => \Hyperf\Filesystem\Adapter\FtpAdapterFactory::class,
'host' => 'ftp.example.com',
'username' => 'username',
'password' => 'password',
/* optional config settings */
'port' => 21,
'root' => '/path/to/root',
'passive' => true,
'ssl' => true,
'timeout' => 30,
'ignorePassiveAddress' => false,
],
'memory' => [
'driver' => \Hyperf\Filesystem\Adapter\MemoryAdapterFactory::class,
],
's3' => [
'driver' => \Hyperf\Filesystem\Adapter\S3AdapterFactory::class,
'credentials' => [
'key' => env('S3_KEY'),
'secret' => env('S3_SECRET'),
],
'region' => env('S3_REGION'),
'version' => 'latest',
'bucket_endpoint' => false,
'use_path_style_endpoint' => false,
'endpoint' => env('S3_ENDPOINT'),
'bucket_name' => env('S3_BUCKET'),
],
'minio' => [
'driver' => \Hyperf\Filesystem\Adapter\S3AdapterFactory::class,
'credentials' => [
'key' => env('S3_KEY'),
'secret' => env('S3_SECRET'),
],
'region' => env('S3_REGION'),
'version' => 'latest',
'bucket_endpoint' => false,
'use_path_style_endpoint' => true,
'endpoint' => env('S3_ENDPOINT'),
'bucket_name' => env('S3_BUCKET'),
],
'oss' => [
'driver' => \Hyperf\Filesystem\Adapter\AliyunOssAdapterFactory::class,
'accessId' => env('OSS_ACCESS_ID'),
'accessSecret' => env('OSS_ACCESS_SECRET'),
'bucket' => env('OSS_BUCKET'),
'endpoint' => env('OSS_ENDPOINT'),
// 'timeout' => 3600,
// 'connectTimeout' => 10,
// 'isCName' => false,
// 'token' => '',
],
'qiniu' => [
'driver' => \Hyperf\Filesystem\Adapter\QiniuAdapterFactory::class,
'accessKey' => env('QINIU_ACCESS_KEY'),
'secretKey' => env('QINIU_SECRET_KEY'),
'bucket' => env('QINIU_BUCKET'),
'domain' => env('QINIU_DOMAIN'),
],
'cos' => [
'driver' => \Hyperf\Filesystem\Adapter\CosAdapterFactory::class,
'region' => env('COS_REGION'),
// overtrue/flysystem-cos ^2.0 配置如下
'credentials' => [
'appId' => env('COS_APPID'),
'secretId' => env('COS_SECRET_ID'),
'secretKey' => env('COS_SECRET_KEY'),
],
// overtrue/flysystem-cos ^3.0 配置如下
'app_id' => env('COS_APPID'),
'secret_id' => env('COS_SECRET_ID'),
'secret_key' => env('COS_SECRET_KEY'),
// 可选,如果 bucket 为私有访问请打开此项
// 'signed_url' => false,
'bucket' => env('COS_BUCKET'),
'read_from_cdn' => false,
// 'timeout' => 60,
// 'connect_timeout' => 60,
// 'cdn' => '',
// 'scheme' => 'https',
],
],
];