Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Flysystem Oss Laravel Package

iidestiny/flysystem-oss

Flysystem adapter for Alibaba Cloud OSS (Aliyun Object Storage Service). Integrate OSS storage with Laravel and PHP apps using Flysystem, enabling file uploads, reads, deletes, and URL generation through a familiar filesystem API.

View on GitHub
Deep Wiki
Context7

Getting Started

This package is a Flysystem adapter, not a Laravel service provider. In Laravel you'll almost always pull it in through its companion, iidestiny/laravel-filesystem-oss, which registers the oss disk driver and depends on this one.

composer require iidestiny/laravel-filesystem-oss

Add the disk in config/filesystems.php:

'oss' => [
    'driver'     => 'oss',
    'access_key' => env('OSS_ACCESS_KEY_ID'),
    'secret_key' => env('OSS_ACCESS_KEY_SECRET'),
    'endpoint'   => env('OSS_ENDPOINT'),   // e.g. oss-cn-hangzhou.aliyuncs.com
    'bucket'     => env('OSS_BUCKET'),
    'is_cname'   => env('OSS_IS_CNAME', false),
    'prefix'     => env('OSS_PREFIX', ''),
    'options'    => [],
],

Your first use case is almost always "store an uploaded file and give the URL back to the frontend":

$path = Storage::disk('oss')->putFile('avatars', $request->file('avatar'));
$url  = Storage::disk('oss')->url($path);      // public bucket only

Where to look first:

  • vendor/iidestiny/flysystem-oss/src/OssAdapter.php — the source of truth for what operations actually map cleanly to OSS.
  • vendor/iidestiny/flysystem-oss/src/Plugins/ — the escape hatches (signed URLs, custom calls) you'll need the moment the bucket isn't public.
  • vendor/iidestiny/laravel-filesystem-oss/src/ — the ServiceProvider and OssStorageServiceProvider that register the driver; check here if Storage::disk('oss') throws "driver not supported."

If you don't need Laravel wiring (queue workers in plain PHP, CLI tools, tests), use the adapter directly:

use League\Flysystem\Filesystem;
use Iidestiny\Flysystem\Oss\OssAdapter;
use OSS\OssClient;

$client  = new OssClient($key, $secret, $endpoint);
$adapter = new OssAdapter($client, $bucket);
$fs      = new Filesystem($adapter);

Implementation Patterns

One disk per bucket, not one disk for everything. OSS buckets are the unit of ACL and region. Model them explicitly:

'oss-media'    => [ 'driver' => 'oss', 'bucket' => 'app-media',   ... ],
'oss-invoices' => [ 'driver' => 'oss', 'bucket' => 'app-invoices', 'is_cname' => true, 'domain' => 'files.example.com', ... ],

Uploads: prefer putFile/putFileAs over put. They stream from the temp file and avoid loading the whole payload into memory.

Storage::disk('oss')->putFileAs('exports', $request->file('csv'), "{$user->id}.csv");

Public vs. private. For a private bucket, ->url() returns a well-formed but useless URL unless the object is public-read. Two reliable options:

  1. Storage::disk('oss')->temporaryUrl($path, now()->addMinutes(10)) — works when the installed adapter version implements Flysystem's TemporaryUrlGenerator (Flysystem 3.x adapters do). Verify against your pinned version.
  2. Go straight to the SDK client:
$adapter = Storage::disk('oss')->getAdapter();
$client  = $adapter->getClient();
$url     = $client->signUrl($bucket, $object, 3600, \OSS\OssClient::OSS_HTTP_GET);

Directory-style keys. OSS is flat; the adapter mimics directories via the / prefix. Use a consistent hierarchy (tenant/{id}/{domain}/...) so you can use Storage::disk('oss')->files('tenant/42') and lifecycle rules on the bucket side.

Cache URL generation. temporaryUrl and signUrl are cheap (HMAC), but they're still per-request work. If you render the same asset repeatedly in one request, memoize.

Streaming and large files. putFile is fine for typical uploads. For multi-GB files you'll want multipart — the plain Flysystem surface doesn't expose it, so reach into the adapter's OssClient for multiuploadFile.

Testing. Don't hit OSS in tests. Swap the disk config in phpunit.xml or TestCase::setUp:

config(['filesystems.disks.oss' => ['driver' => 'local', 'root' => storage_path('framework/testing/oss')]]);

For assertions on calls, fake the disk: Storage::fake('oss') only works if the fake driver supports it — use a local disk and assert on real files instead.

Queued work. OSS calls are network-bound; wrap uploads/downloads in jobs when they're part of a user-facing flow. The OssClient isn't serializable, so resolve the disk from the container inside the job, never inject the Filesystem instance.

Gotchas and Tips

  • Endpoint formatting. Pass the host, not a URL: oss-cn-hangzhou.aliyuncs.com. If you pass https://... some versions double-prefix or sign incorrectly. is_cname=true requires a CNAME-bound domain and changes URL generation — flip it together with domain, not independently.
  • Flysystem major-version skew. Flysystem 1/2/3 have different adapter contracts. If Storage::disk('oss')->url() or temporaryUrl() suddenly throws MethodNotImplemented, you're on a version pair that doesn't ship the generator interface. Pin iidestiny/flysystem-oss and its Laravel wrapper together; don't composer update one without the other.
  • visibility maps to OSS ACL, not POSIX permissions. public-read is the value OSS accepts from the Flysystem abstraction; anything else may be silently ignored depending on adapter version. If objects land private when you expected public, set the bucket-level ACL or pass options => ['ACL' => 'public-read'].
  • prefix vs. path in the call. The prefix is prepended before signing and listing. If you set prefix = 'uploads' and then call put('users/1.png'), the stored key is uploads/users/1.png. It's easy to double-prefix in a job that already includes the prefix in the path — pick one convention per project.
  • Region mismatch is the #1 production error. A client configured for cn-hangzhou against a cn-shanghai bucket produces confusing RequestTimeTooSkewed / AccessDenied errors. Verify the endpoint against the bucket console before debugging credentials.
  • Time skew causes signature failures (RequestTimeTooSkewed) that look like auth bugs. In containers, ensure NTP.
  • Error types. The package wraps SDK exceptions in Flysystem UnableTo* exceptions. Catch League\Flysystem\FilesystemException at the boundary, but log the underlying OSS\Core\OssException code — the Flysystem message collapses the useful detail.
  • options array is your escape hatch, passed through to the SDK for put/get/delete. Use it for Content-Disposition, server-side encryption headers, or storage class — but test each key, since the adapter filters some.
  • Extension points: $adapter->addPlugin(...) for custom operations (e.g., a pre-configured signUrl plugin you expose through a disk macro). For deep customization (multipart, object tagging, inventory listings) drop to $adapter->getClient(). Wrap those calls in your own class so you don't scatter OssClient usage through application code.
  • Cost and latency: exists() and stat() are round-trips. If a controller does exists() + get() + url() for the same key, that's three calls — batch or cache the metadata. Also, cross-region traffic between your app server and the OSS endpoint is billed; co-locate.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource