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

Sdk Laravel Package

upyun/sdk

Official PHP SDK for UPYUN cloud storage, offering simple APIs for uploading, downloading, deleting, and managing files, generating upload tokens, and integrating UPYUN storage and CDN services into Laravel or plain PHP applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the SDK directly — there is no Laravel service provider, facade, or config publishing, so all wiring is yours:

composer require upyun/sdk

Add credentials to config/services.php (create the entry yourself) and keep secrets in .env:

// config/services.php
'upyun' => [
    'bucket'   => env('UPYUN_BUCKET'),
    'operator' => env('UPYUN_OPERATOR'),
    'password' => env('UPYUN_PASSWORD'),
    'domain'   => env('UPYUN_DOMAIN'),   // CDN / file-access domain, NOT the API host
    'timeout'  => env('UPYUN_TIMEOUT', 120),
],

Register a singleton so the client (and its cURL handle setup) is reused per request:

// app/Providers/UpyunServiceProvider.php
public function register(): void
{
    $this->app->singleton(\Upyun\Upyun::class, function ($app) {
        $c = $app['config']['services.upyun'];
        $config = new \Upyun\Config($c['bucket'], $c['operator'], $c['password']);
        $config->setTimeout($c['timeout']);

        return new \Upyun\Upyun($config);
    });
}

Where to look first: the README's short examples, then src/Upyun.php (the public surface: write, read, delete, info, has, listing) and src/Config.php (the handful of setters — timeout, API domain, upload type). The src/Api/ layer is where listing, bucket usage, and directory operations actually live, so drop down there when a top-level method is missing.

First use case: store a generated file and read it back. This exercises the whole loop — auth signature, upload, HEAD metadata, and retrieval — in about ten lines:

use Upyun\Upyun;

public function store(Upyun $client, UploadedFile $file, int $userId): string
{
    $path = "/avatars/{$userId}.jpg";

    $client->write($path, fopen($file->getRealPath(), 'r'), [
        'Content-Type' => $file->getMimeType(),
    ]);

    return config('services.upyun.domain') . $path; // CDN URL
}

Implementation Patterns

Wrap it behind your own interface. The single highest-value pattern: define App\Contracts\ObjectStore (put, get, delete, exists, url, list) and implement it with this SDK. UPYUN's flat-key semantics and the SDK's exception style leak everywhere otherwise, and a swap to S3 or R2 later becomes a one-class change rather than a grep across the codebase.

Stream, don't buffer. write() accepts a stream resource as well as a string; for anything user-uploaded, always pass fopen($tmpPath, 'r'). read($path) returns the body as a string, so for downloads prefer read($path, $localPath), which writes straight to disk.

Upload in a queued job with retry(). The SDK has no retry, backoff, or circuit breaker. Do it at the Laravel layer:

retry(3, fn () => $client->write($path, $stream), 500, fn ($e) => $e instanceof \Exception);

Keep the temporary file alive until the job succeeds (delete in finally, not before dispatch).

Custom metadata via headers. The third write() argument is a header array. Beyond Content-Type, you can attach x-upyun-meta-* headers and use them as cheap per-object tags (uploader id, original filename) instead of a separate metadata table — but cap total header size, UPYUN rejects oversized metadata.

Store keys in the database, not URLs. Persist uploads/2024/report.pdf and build the public URL at render time from services.upyun.domain. That lets you switch the access domain, add a token, or move behind a CDN without a data migration.

Listing is paginated and lazy. getFiles($path) yields entries and transparently walks the iter cursor when the directory exceeds a page. Consume it as a generator (foreach), never iterator_to_array() on a large prefix, and persist a cursor/marker if you need resumable syncs.

Mix in Flysystem for standard operations. If all you need is Storage::disk('upyun')->put(...), a Flysystem UPYUN adapter (e.g. overtrue/flysystem-upyun) is less code. Verify the adapter's Flysystem major version matches your Laravel (9+ ships Flysystem 3). Use this SDK directly for the things adapters don't expose: info() metadata, bucket usage, form-API uploads, and custom headers.

Form API vs. REST. Config can switch upload type; form-API uploads are the right choice when the browser talks to UPYUN directly and only hands your server a signature. Keep your server in REST mode and generate form signatures as a separate, tightly-scoped endpoint if you go that route.

Gotchas and Tips

  • Laravel's Http::fake() will not intercept this SDK. It uses raw cURL, so any test that touches it hits the network. Fake your own ObjectStore interface in tests — this alone justifies the wrapper pattern.
  • "Directories" don't exist. Keys are flat; a/b/c.jpg is one key. There is no recursive delete — list the prefix and delete each key (batch it in a job). Leading slashes are convention, not structure, so be consistent or you'll create /foo/x and foo/x as distinct keys.
  • read() without a destination path loads the whole object into memory. Easy way to blow a memory limit on a 200 MB download.
  • The domain and the API host are different things. v0.api.upyun.com (and the v1–v3 ISP variants you can select via the API-domain setter) is control-plane only. Asset URLs come from the bucket's access domain. Confusing them produces URLs that 404 even though the upload succeeded.
  • Missing keys throw, they don't return falsy. Wrap read/info in try/catch, or call has() first. Map upstream errors to Laravel exceptions (NotFoundHttpException, HttpException(503)) inside your adapter so controllers stay clean.
  • Set the timeout explicitly. Large uploads on a slow link exceed the default easily; the symptom is a truncated stream with an opaque cURL error rather than a clean API error code.
  • Set Content-Type yourself. Content-Type inference from the key's extension is unreliable, and a wrong type sticks at the CDN edge until you re-upload the same key with corrected headers.
  • Anti-leech/token signing is not in the SDK. If the bucket is private or token-protected, you must compute the _upt token (MD5 of token secret + file etag + expiry) yourself. Cache etags from info() — the ETag is what the token is bound to, so re-uploading invalidates every previously generated URL.
  • Use a least-privilege operator. A dedicated operator with write-only permission for upload paths limits the blast radius if the password leaks from a misconfigured env. Never ship the operator password to the front end — that's what form-API signatures are for.
  • Maintenance risk is real. Last release was mid-2020 and there's no active Laravel ecosystem adoption. Pin the version, read the source when behaviour surprises you (the docs are thin), and prefer the REST endpoints the SDK wraps over expecting new features. It runs fine on PHP 8, but you may see deprecation notices from older internal code, and there are no typed signatures to lean on for IDE support.
  • Testing seams: point the client at a stub host or inject your ObjectStore fake; assert the keys and paths your app produces, since that's where the real bugs live (double slashes, missing prefix, wrong case in the extension).
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.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib