vergil-lai / laravel-oss-filesystem
Aliyun OSS filesystem driver for Laravel using the Alibaba Cloud OSS PHP SDK v2.
Package info
github.com/vergil-lai/laravel-oss-filesystem
pkg:composer/vergil-lai/laravel-oss-filesystem
Requires
- php: ^8.2
- alibabacloud/oss-v2: ^0.4
- illuminate/container: ^12.0|^13.0
- illuminate/contracts: ^12.0|^13.0
- illuminate/filesystem: ^12.0|^13.0
- illuminate/support: ^12.0|^13.0
- league/flysystem: ^3.19
- vergil-lai/oss-flysystem: ^1.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.75
- larastan/larastan: ^3.0
- pestphp/pest: ^3.0|^4.0
- phpstan/phpstan: ^2.0
README
基于 alibabacloud/oss-v2 的 Laravel 阿里云 OSS filesystem 驱动。
Laravel 集成基于独立的 vergil-lai/oss-flysystem 包;Laravel 用户只需安装当前包,Composer 会自动安装底层依赖。
要求
- PHP 8.2+
- Laravel 12/13
安装
composer require vergil-lai/laravel-oss-filesystem
配置
在应用的 config/filesystems.php 中,将以下配置加入 disks。本包会先加载内部默认值,再用这里的 disks.oss 配置覆盖默认值。
region 和 bucket 是通常需要配置的参数。凭证可以使用 access_key_id、access_key_secret 和可选的 security_token,也可以程序化注入 credentials_provider。其余参数按实际环境选填。
'disks' => [ // ... 'oss' => [ // Laravel filesystem 驱动名称,固定为 oss。 'driver' => 'oss', // 自定义 SDK 凭证提供器;配置后优先于下面的静态凭证。 'credentials_provider' => null, // 阿里云 AccessKey ID。 'access_key_id' => env('OSS_ACCESS_KEY_ID'), // 阿里云 AccessKey Secret。 'access_key_secret' => env('OSS_ACCESS_KEY_SECRET'), // 使用 STS 临时凭证时的 Security Token,长期凭证无需配置。 'security_token' => env('OSS_SESSION_TOKEN'), // 请求签名版本,支持 v4 和 v1,默认使用 v4。 'signature_version' => env('OSS_SIGNATURE_VERSION', 'v4'), // Bucket 所在地域;使用 V4 签名时必须正确配置。 'region' => env('OSS_REGION', 'cn-hangzhou'), // 要访问的 OSS Bucket 名称。 'bucket' => env('OSS_BUCKET'), // 自定义 OSS Endpoint;留空时由 SDK 根据地域和模式生成。 'endpoint' => env('OSS_ENDPOINT'), // Disk 内所有对象键统一添加的路径前缀。 'root' => env('OSS_ROOT', ''), // 生成公开 URL 时使用的自定义基础地址。 'url' => env('OSS_URL'), // 默认可见性,可设为 private 或 public。 'visibility' => env('OSS_VISIBILITY', 'private'), // 操作失败时是否抛出 Flysystem 异常。 'throw' => env('OSS_THROW', false), // SDK 发起 HTTP 请求时使用的代理地址。 'proxy_host' => env('OSS_PROXY_HOST', env('OSS_PROXY')), // 追加到 SDK User-Agent 请求头的自定义标识。 'user_agent' => env('OSS_USER_AGENT'), // 建立连接的超时时间,单位为秒。 'connect_timeout' => env('OSS_CONNECT_TIMEOUT'), // 读写请求的超时时间,单位为秒。 'read_write_timeout' => env('OSS_READ_WRITE_TIMEOUT'), // API 请求失败后的最大尝试次数。 'retry_max_attempts' => env('OSS_RETRY_MAX_ATTEMPTS'), // 自定义 SDK 重试器;留空时使用 SDK 默认重试器。 'retryer' => null, // Endpoint 是否为绑定到 Bucket 的自定义 CNAME 域名。 'use_cname' => env('OSS_USE_CNAME', false), // 是否使用路径风格地址,即在 URL 路径中携带 Bucket 名称。 'use_path_style' => env('OSS_USE_PATH_STYLE', false), // 是否使用阿里云内网 Endpoint。 'use_internal_endpoint' => env('OSS_USE_INTERNAL_ENDPOINT', false), // 是否使用 OSS 传输加速 Endpoint。 'use_accelerate_endpoint' => env('OSS_USE_ACCELERATE_ENDPOINT', false), // 是否使用同时支持 IPv4 和 IPv6 的双栈 Endpoint。 'use_dual_stack_endpoint' => env('OSS_USE_DUAL_STACK_ENDPOINT', false), // 是否禁用 HTTPS 并改用 HTTP。 'disable_ssl' => env('OSS_DISABLE_SSL', false), // 是否允许 HTTP 请求自动跟随重定向。 'enabled_redirect' => env('OSS_ENABLED_REDIRECT', false), // 是否跳过 TLS 证书校验;仅应在受控环境中启用。 'insecure_skip_verify' => env('OSS_INSECURE_SKIP_VERIFY', false), // V4 签名时需要额外纳入签名计算的请求头名称。 'additional_headers' => [], // 阿里云云盒 ID;仅在使用云盒 OSS 时配置。 'cloud_box_id' => env('OSS_CLOUD_BOX_ID'), // 是否让 SDK 自动探测阿里云云盒 ID。 'enable_auto_detect_cloud_box_id' => env('OSS_ENABLE_AUTO_DETECT_CLOUD_BOX_ID', false), // 传给底层 Guzzle HTTP 客户端的自定义选项。 'client_options' => [], ], ],
和旧版 aliyuncs/oss-sdk-php 的配置相比,这里有几个差异:
prefix在 Laravel/Flysystem 里对应rootrequest_proxy对应 SDK v2 的proxy_hosttimeout对应 SDK v2 的read_write_timeoutuse_ssl改为 SDK v2 的反向语义disable_sslsignatureVersion对应signature_version,支持v4和v1,默认使用v4- 不提供旧包的
macros和options
自定义凭证提供器和重试器
credentials_provider 接受 SDK 的 CredentialsProvider 实现,设置后优先于 access_key_id、access_key_secret 和 security_token。retryer 接受 SDK 的 RetryerInterface 实现。
这两个参数是对象,不建议直接写进 config/filesystems.php,否则可能影响 Laravel 的 config:cache。可以在应用的 Service Provider 中、首次解析 OSS disk 前注入:
use AlibabaCloud\Oss\V2\Credentials\EnvironmentVariableCredentialsProvider; use AlibabaCloud\Oss\V2\Retry\StandardRetryer; public function register(): void { config()->set( 'filesystems.disks.oss.credentials_provider', new EnvironmentVariableCredentialsProvider(), ); config()->set( 'filesystems.disks.oss.retryer', new StandardRetryer(maxAttempts: 5), ); }
如果没有设置 retryer,SDK 会使用默认的 StandardRetryer。仅需调整最大重试次数时,直接配置 retry_max_attempts 即可。
自定义 HTTP 客户端
底层 SDK 的 AlibabaCloud\Oss\V2\Client 第二个参数支持传入 Guzzle 选项。你可以通过 client_options 透传这些配置:
'oss' => [ 'driver' => 'oss', // ... 'client_options' => [ 'handler' => \GuzzleHttp\HandlerStack::create($handler), 'request_options' => [ 'connect_timeout' => 10.0, 'timeout' => 30.0, ], ], ],
在 Laravel Octane + Swoole 环境下,如果应用额外安装了 hyperf/guzzle,本包会自动尝试使用其协程 handler:
composer require hyperf/guzzle
已经显式配置的 client_options.handler 会被原样保留,不会被自动优化覆盖。
注入原生 SDK Client
client 接受 AlibabaCloud\Oss\V2\Client 实例。设置后,本包不会再根据数组配置创建客户端:
use AlibabaCloud\Oss\V2\Client; use AlibabaCloud\Oss\V2\Config as OssConfig; use AlibabaCloud\Oss\V2\Credentials\EnvironmentVariableCredentialsProvider; $sdkConfig = OssConfig::loadDefault(); $sdkConfig->setRegion('cn-hangzhou'); $sdkConfig->setCredentialsProvider(new EnvironmentVariableCredentialsProvider()); config()->set('filesystems.disks.oss.client', new Client($sdkConfig));
自定义 Client 同样不建议直接写入配置文件,应在首次解析 OSS disk 前程序化注入。公开 URL 仍由 disk 的 url、endpoint、region 和 endpoint 模式配置生成。
支持的操作
put、get、流式读写exists、文件大小、MIME 类型、最后修改时间、可见性- 递归列出文件和删除目录
- 复制、移动、删除
- 通过
url生成公开访问地址 - 通过
temporaryUrl生成临时 GET 访问地址 - 通过
temporaryUploadUrl生成临时 PUT 上传地址 - 上传时支持
visibility、mimetype、cache_control、content_disposition、content_encoding、metadata、forbid_overwrite、storage_class等常见选项 checksum默认使用 OSS ETag,不会为了计算校验值下载完整对象
使用
Storage::disk('oss')->put('avatars/me.png', $contents); $url = Storage::disk('oss')->url('avatars/me.png'); $temporaryUrl = Storage::disk('oss')->temporaryUrl('avatars/me.png', now()->addMinutes(10)); $temporaryUpload = Storage::disk('oss')->temporaryUploadUrl('avatars/me.png', now()->addMinutes(10));
详细请查看官方文档