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

Weed Php Laravel Package

micjohnson/weed-php

Weed is a Laravel/PHP package that helps you weed out unused CSS. It scans your Blade views and templates, then generates a leaner stylesheet so your app ships less dead code, loads faster, and stays easier to maintain.

Deep Wiki
Context7

Getting Started

micjohnson/weed-php is a thin HTTP client for a Weed-FS (now SeaweedFS) cluster. It does not ship a Laravel service provider or facade, so treat it as a library you wire up yourself.

Install

composer require micjohnson/weed-php

Where to look first

  1. Read the package's README.md and the src/ classes for the exact method names — the API surface is small (assign/upload/get/delete against master + volume servers) but method signatures vary between forks. Do not assume the examples below compile; confirm against vendor/micjohnson/weed-php/src.
  2. Confirm which SeaweedFS generation your cluster runs. Weed-FS was renamed SeaweedFS and the HTTP endpoints/response shapes changed between 0.x and 1.x+. This package targets the older Weed-FS master/volume HTTP API.
  3. Check the HTTP client dependency (Guzzle version pinned in composer.json) against your app's existing Guzzle — see Gotchas.

Configure

You need at minimum a master endpoint; volume servers are discovered/redirected to.

// config/weed.php
return [
    'master' => env('WEED_MASTER', 'http://seaweed-master:9333'),
    'timeout' => 5,
];

First use case — store a file and keep the file ID

use Micjohnson\WeedPhp\WeedClient; // verify exact namespace in vendor/

$client = new WeedClient(config('weed.master'));

// 1. Ask the master for a new file id (fid), e.g. "3,01637037d6"
$fid = $client->assign();        // method name may differ: assignFileId / allocate

// 2. Upload bytes to the assigned volume server
$client->upload($fid, $contents); // or write($fid, $fh)

// 3. Persist the fid — it is the only handle you need
Document::create(['weed_fid' => $fid, 'filename' => 'contract.pdf']);

// 4. Later: fetch by fid
$bytes = $client->get($fid);

The mental model: the fid is your primary key. The master only allocates IDs and tracks volumes; the data lives on volume servers addressed by the fid's volume component. Everything you build around this package is really fid lifecycle management.

Implementation Patterns

Wrap it in a service provider + facade. Since there's no auto-discovery, bind the client as a singleton so connection config lives in one place:

class WeedServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->singleton(WeedClient::class, fn () =>
            new WeedClient(config('weed.master'), config('weed.timeout'))
        );
    }
}

Then inject WeedClient into services. This also gives you a seam to swap in a fake for tests.

Store the fid, not the URL. Volume server hostnames change as volumes are rebalanced. Persist (fid, filename, size, content_type, checksum) and reconstruct URLs/downloads at read time via the master lookup or volume redirect. Never persist a resolved http://volume-host:8080/3,abc URL.

Two-phase upload for large files. The assign → upload split is a feature: allocate the fid first, write the row in pending status, upload, then flip to ready. If the upload dies you have an orphan fid you can reap with a scheduled job rather than a silently missing file.

Stream, don't slurp. For anything above a few MB, stream from a temp file or stream resource rather than passing a whole string. Use fopen on the source, hand the handle to the client (if supported) or chunk it, and stream the download to a StreamedResponse:

return response()->streamDownload(function () use ($client, $doc) {
    echo $client->get($doc->weed_fid);
}, $doc->filename);

Queue the upload. Uploads hit a specific volume server, which can be slow or return redirects. Push uploads onto a queue job and let the HTTP request return fast; keep a weed_fid column nullable until the job succeeds.

Retry with idempotency in mind. Uploads are effectively idempotent per fid (overwriting the same fid rewrites the needle). Wrap upload in a retry ($this->release(10) in a job), but guard the assign step so retries don't leak new fids — either reuse the fid already stored or clean up the abandoned one.

Local test double. Because the master/volume split is awkward to run locally, point the client at a fake implementing the same interface in tests. This is where binding an interface rather than the concrete WeedClient pays off.

Cleanup job. A nightly task should scan pending rows older than N hours, call delete for their fids, and mark them abandoned. Without this, failed uploads silently consume volume space.

Gotchas and Tips

It's the old Weed-FS API, not necessarily SeaweedFS. SeaweedFS deprecated and later removed some endpoints this client relies on, and changed response fields (e.g. Fid/Url casing, /dir/assign semantics). If the master returns something your client can't parse, that's the first suspect. Check $client->assign() against a raw curl http://master:9333/dir/assign to isolate client vs cluster.

Volume servers redirect — make sure the HTTP client follows them. Uploads often get a 307 to the actual volume host. If Guzzle is configured with allow_redirects => false globally in your app, uploads will mysteriously "succeed" with an empty body. Set redirects explicitly on the client's request options, not just globally.

fid parsing is easy to get wrong. A fid is volumeId,needleId (needle ID hex). Splitting on , to build URLs works, but trimming or lowercasing the hex breaks lookups. Store fids verbatim as VARCHAR, not BINARY, and never round-trip through integer casts.

Guzzle version conflicts. If the package pins guzzlehttp/guzzle:^5 or ~6.0, you'll get a Composer conflict with a Laravel 9+/10+ app on Guzzle 7. Options: alias/patch the package, or extract the few HTTP calls into your own small client using the app's Guzzle 7 — often cleaner than fighting the lockfile for a 20-star package.

No TLS / auth in the client. Weed-FS's HTTP API has no authentication. This client will happily talk plaintext to whatever host you give it. Keep the cluster on a private network, do not expose volume ports, and terminate anything public behind your own Laravel auth layer. Don't put the master URL in client-facing config or errors.

Master down = no new uploads, existing reads may still work. Reads can go straight to the volume server if you cached a host, but this package likely resolves through the master. Build in a fast failure (connect_timeout of 1–2s) so a flaky master doesn't hang your web requests.

Timeouts and memory are your two failure modes. Set an explicit read timeout high enough for big uploads but bounded, and cap upload_max_filesize/post_max_size in PHP equal to your app limit — otherwise the client streams a large body into memory before PHP's own limits kick in and you get confusing OOMs instead of a 413.

Deletes need the fid, not a path — and are best-effort. There's no rename/overwrite-by-name. Deletion marks the needle; space is reclaimed by volume compaction, so "deleted" files may linger on disk. Don't rely on delete for compliance/erasure guarantees — use SeaweedFS TTL settings at the volume level if you need that.

Extension points are thin. Don't expect hooks, events, or a logger. If you need observability, wrap the client in your own service that logs each assign/upload/get/delete with timing and fid, and increment metrics. That wrapper is also the right place to add circuit-breaking and retry policy, keeping the vendor class dumb.

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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
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