district5 / slim-psr-upload-handler
一个易于使用、基于提供者的上传处理程序,适用于Slim框架。
1.0.1
2024-03-13 13:58 UTC
Requires
- php: >=8.1
- ext-fileinfo: *
- aws/aws-sdk-php: 3.*
- google/cloud-storage: ^1.39
- php-di/slim-bridge: ^3.0
- slim/psr7: ^1.6
This package is auto-updated.
Last update: 2024-09-21 13:31:20 UTC
README
简介...
这是一个简单的Slim框架上传处理程序。它设计为与PSR接口一起使用,并且与Slim 4兼容。
提供者包括以下内容:Google Cloud Storage、AWS S3和本地文件。
只需安装即可
composer require district5/slim-psr-upload-handler
支持的提供者...
- 本地文件(键:
local
)- 此提供者会将文件保存到本地目录。
- 配置
path
(字符串)- 保存文件的目录。overwrite
(布尔值)- 如果文件已存在,则覆盖文件。appendRandom
(布尔值)- 将随机字符串附加到文件名。suppressExceptions
(布尔值)- 忽略错误并返回UploadedDto对象。覆盖全局suppressExceptions
选项。
- Google Cloud Storage(键:
gcs
)- 此提供者会将文件保存到Google Cloud Storage。
- 配置
projectId
(字符串)- Google Cloud项目ID。bucket
(字符串)- 您的Google Cloud Storage存储桶名称。path
(字符串)- 文件在存储桶中的路径,例如'uploads'或'images'。留空(或null)表示根目录。keyFile
(数组)- 服务账户密钥文件的JSON解码(即数组)版本。overwrite
(布尔值)- 如果文件已存在,则覆盖文件。appendRandom
(布尔值)- 将随机字符串附加到文件名。acl
(字符串)- Google Cloud Storage对象的ACL。suppressExceptions
(布尔值)- 忽略错误并返回UploadedDto对象。覆盖全局suppressExceptions
选项。
- AWS S3(键:
s3
)- 此提供者会将文件保存到Amazon S3。
- 配置
region
(字符串)- 存储桶所在的区域。version
(字符串)- 要使用的S3 API版本。bucket
(字符串)- 存储桶的名称。path
(字符串)- 文件在存储桶中的路径,例如'uploads'或'images'。留空(或null)表示根目录。accessKey
(字符串)- 存储桶的访问密钥。secretKey
(字符串)- 存储桶的秘密密钥。overwrite
(布尔值)- 如果文件已存在,则覆盖文件。appendRandom
(布尔值)- 将随机字符串附加到文件名。acl
(字符串)- 对象的ACL(public-read、private等)。suppressExceptions
(布尔值)- 忽略错误并返回UploadedDto对象。覆盖全局suppressExceptions
选项。
用法...
<?php use \District5\UploadHandler\UploadHandler; use \Slim\Psr7\Request; use \Slim\Psr7\Response; $container = new \Slim\Container(); // ... add any other dependencies to the container before or after the upload handler $uploadHandlerConfig = [ 'options' => [ // these are the core library options. these are the defaults for all handlers, but can be overridden in the handler specific config 'suppressExceptions' => false, // ignore errors and return the UploadedDto object regardless. 'appendRandom' => true, // append a random string (using uniqid) to the file, or use the original name ], 'handlers' => [ 'example-google-cloud-storage-provider' => [ // 'my-gcs-provider' is the action name, this can be anything you want 'provider' => 'gcs', // Or use the class name of GcsProvider::class 'config' => [ 'suppressExceptions' => false, // Override the global suppressExceptions option 'appendRandom' => false, // append a random string (using uniqid) to the file, or use the original name. Overrides the global appendRandom option 'overwrite' => false, // overwrite the file if it already exists 'projectId' => $env->get('GCS_PROJECT_ID'), // your GCP project id 'bucket' => $env->get('GCS_BUCKET'), // your GCS bucket name 'path' => $env->get('GCS_OBJECT_PATH'), // or null/empty string for root 'keyFile' => json_decode($env->get('GCS_KEY_FILE_CONTENT'), true), // your GCP service account key file content, 'acl' => $env->get('GCS_OBJECT_ACL'), // the GCS object ACL ] ], 'example-aws-s3-provider' => [ // 'generic-file' is the action name, this can be anything you want 'provider' => 's3', 'config' => [ 'suppressExceptions' => false, // suppress exceptions, or let them bubble up 'appendRandom' => true, // append a random string (using uniqid) to the file, or use the original name. Overrides the global appendRandom option 'overwrite' => false, // overwrite the file if it already exists 'region' => $env->get('S3_REGION'), // the region of the bucket 'version' => $env->get('S3_VERSION'), // the version of the S3 API to use (typically 'latest') 'bucket' => $env->get('S3_BUCKET'), // the name of the bucket 'path' => $env->get('S3_OBJECT_PATH'), // or null/empty string for root 'accessKey' => $env->get('S3_ACCESS_KEY'), // the access key for the bucket 'secretKey' => $env->get('S3_SECRET_KEY'), // the secret key for the bucket 'acl' => $env->get('S3_OBJECT_ACL') // the acl for the object (public-read, private, etc.) ] ], 'example-local-file-provider' => [ // 'generic-file' is the action name, this can be anything you want 'provider' => 'local', // Or use the class name of LocalFileProvider::class 'config' => [ // 'suppressExceptions' => false, // Override the global suppressExceptions option // 'appendRandom' => false, // append a random string (using uniqid) to the file, or use the original name. Overrides the global appendRandom option 'overwrite' => false, // overwrite the file if it already exists 'path' => $env->get('LOCAL_WRITABLE_DIRECTORY'), // the directory to save the file to (trailing slash is stripped) ] ] ] ]; UploadHandler::create($container, $uploadHandlerConfig); $app = new \Slim\App($container); $app->post('/upload', function (Request $request, Response $response, $args) { $file = $request->getUploadedFiles()['param-key']; /* @var $container \DI\Container */ $uploadHandler = $container->get(UploadHandler::class); /* @var $uploadHandler UploadHandler */ $result = $uploadHandler->handleFromUpload('example-google-cloud-storage-provider', $file); // or: $result = $uploadHandler->handleFromUpload('example-local-file-provider', $filePath); return $response->withJson($result); });
同样,您也可以从本地文件路径上传...
$app->post('/upload', function (Request $request, Response $response, $args) { $filePath = '/path/to/file.jpg'; /* @var $container \DI\Container */ $uploadHandler = $container->get(UploadHandler::class); /* @var $uploadHandler UploadHandler */ $result = $uploadHandler->handleFromLocal('example-google-cloud-storage-provider', $filePath); // or: $result = $uploadHandler->handleFromLocal('example-local-file-provider', $filePath); return $response->withJson($result); });
创建自己的提供者...
要创建自己的提供者,您需要扩展District5\UploadHandler\Provider\ProviderAbstract
类。该ProviderAbstract
类为您提供了大量的样板代码。
最终,需要实现三个方法
processFileFromUpload
- 当文件上传时调用此方法,并是Slim\Psr7\UploadedFile
对象。processFileFromLocal
- 当文件从本地文件路径上传时调用此方法。getRequiredConfigKeys
- 此方法应返回一个包含必需配置键的数组。
还有可选方法可以覆盖
getOptionalConfigKeys
- 此方法应返回一个包含配置键到值的数组,这些值不是必需提供的,并且可以默认为某个值。例如,如果您在上传前添加图像缩放,则可以使用...protected function getOptionalConfigKeys(): array { return [ 'allowedExtensions' => ['jpg', 'jpeg', 'png', 'gif'], 'maxWidth' => 1920, ]; }
最终,这些值将提供默认值,除非在handlers
配置数组中覆盖了提供者在初始配置中的值。
<?php use Slim\Psr7\UploadedFile; use District5\UploadHandler\Providers\ProviderAbstract; use District5\UploadHandler\UploadedDto; /** * Class MyFileProvider */ class MyFileProvider extends ProviderAbstract { /** * @param UploadedFile $file * @return UploadedDto */ protected function processFileFromUpload(UploadedFile $file): UploadedDto { try { $fileName = $file->getClientFilename(); $newFileName = $this->getFileName($fileName); // this handles the appending of a random string if required $localDirectory = $this->getConfig('path'); $localPath = rtrim($localDirectory, DIRECTORY_SEPARATOR) . '/' . $newFileName; $file->moveTo($localPath); return new UploadedDto( $this, null, $localPath, $file->getClientFilename(), $newFileName, $file->getClientMediaType(), $file->getSize(), pathinfo($localPath), true ); } catch (Throwable $e) { if ($this->suppressException()) { return UploadedDto::createError($this, $e); } throw $e; // re-throw the exception } } /** * @param string $filePath * @return UploadedDto */ protected function processFileFromLocal(string $filePath): UploadedDto { try { $fileName = basename($filePath); $newFileName = $this->getFileName($fileName); $localDirectory = $this->getConfig('path'); $localPath = rtrim($localDirectory, DIRECTORY_SEPARATOR) . '/' . $newFileName; copy($filePath, $localPath); $mime = finfo_file(finfo_open(FILEINFO_MIME_TYPE), $filePath); $size = filesize($filePath); return new UploadedDto( $this, null, $localPath, $baseName, $newFileName, $mime, $size, pathinfo($localPath), true ); } catch (Throwable $e) { if ($this->suppressException()) { return UploadedDto::createError($this, $e); } throw $e; // re-throw the exception } } /** * Get an array of required config keys. No values, just the keys. * * @return array */ protected function getRequiredConfigKeys(): array { return ['path']; } }
要使用此提供者,您需要在UploadHandler
配置中的handlers
数组中添加它。
$uploadHandlerConfig = [ 'handlers' => [ 'my-file-provider' => [ // 'my-file-provider' is the action name, this can be anything you want 'provider' => MyFileProvider::class, // the class name of your provider 'config' => [ // the configuration for your provider 'path' => '/tmp' ] ] ] ];