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 Php Laravel Package

mirafive/sdk-php

A PHP SDK for integrating Mirafive services into your applications. Install via Composer, configure your credentials, and interact with the API through a simple, consistent client designed for PHP and Laravel projects.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a framework-agnostic PHP SDK, not a Laravel package — there is no service provider, facade, or published config file in v1.0.0. Plan on ~20 lines of glue code before your first event lands.

  1. Install: composer require mirafive/sdk-php. You will also want a PSR-18 client + PSR-17 factories (Guzzle works, or symfony/http-client) and a PSR-16 cache implementation (Illuminate\Contracts\Cache\Repository is not PSR-16 — use cache()->store('redis') wrapped, or symfony/cache backed by the same Redis).
  2. First use case — instrumentation, not flags. Bind a single MiraFive\Mira instance as a singleton in AppServiceProvider::register() with your API key, host (defaults to Mira::DEFAULT_HOST), and enabled: false for local/testing. Then track() from a controller or listener and confirm the batch actually leaves the process with an explicit flush() in a tinker session.
  3. Only after events are flowing, wire MiraFive\Flags\MiraFlags. It is a separate object with its own configuration (document:, the PSR-16 cache, flagsRefreshSeconds) and a separate failure domain. Treat it as a second integration.

Look first at the two things that decide whether this package is viable for you: how transport is selected (cURL vs streams vs PSR-18) and whether you have a shared PSR-16 cache in production. Almost every rough edge below traces back to one of those.

Implementation Patterns

Singleton + explicit flush at the end of the request. flush() fires on shutdown and on destruction, but "on shutdown" in PHP-FPM means after the response is already on the wire — on a slow or timed-out flush you are burning a worker. For anything request-scoped, flush deliberately:

// AppServiceProvider
$this->app->singleton(Mira::class, fn () => new Mira(
    apiKey: config('services.mira.key'),
    transport: $this->app->make(ClientInterface::class), // PSR-18
    cache: $psr16,                                      // unlocks breaker + exposure state
    enabled: ! $this->app->environment(['local', 'testing']),
));
// terminable middleware
public function terminate($request, $response): void
{
    app(Mira::class)->flush(); // bounded by flushDeadlineMs (3s default)
}

Queued delivery via handOff / deliverPrepared(). This is the seam worth building around if event volume matters. On track(), hand the prepared payload to a job and let the queue worker perform the network call. You get real retries, real observability, and the web request never touches the network. The SDK's own retry/backoff only helps if the process stays alive long enough to use it — a queue worker does.

Track before you enqueue work, identify once per user per session. track() and identify() are buffered; the batch is capped at 1000 events and 1 MiB, so a fat property bag splits your batch rather than raising an error. Keep properties small and stable — the SDK measures them the way the collector does, so a payload that passes locally should pass remotely, but oversized single events are still your problem to debug.

Flags: resolve once, read many. MiraFlags revalidates the document via ETag, so the steady state is a cheap 304 — but you still do not want a network round trip per Blade partial. Resolve the document once per request (or per octane request), stash it on the container, and evaluate flags off the in-memory copy. Exposures are counted server-side by the evaluator, so evaluating flags anywhere other than where you intend to record exposure will distort your metrics.

Browser handoff. MiraFlags::snapshot() returns the document JSON, and the package emits an escaped bootstrap block for the browser SDK. Use the escaped block rather than hand-rolling json_encode into a <script> tag — the escaping is the whole point. When the browser needs a document you already fetched server-side, pass document: MiraFlags::snapshot() so you do not refetch.

Testing. enabled: false short-circuits network calls — use it globally in phpunit.xml. Then unit-test your own event mapping by asserting against what you handed to handOff, not against a fake HTTP client. For flag logic, the evaluator passes the shared MIRA FIVE fixtures; mirror those fixtures in your tests so a vendor upgrade that changes semantics shows up as a failing assertion rather than a production surprise.

Gotchas and Tips

The circuit breaker lives in the PSR-16 cache — or it doesn't. Without a cache, a failed flush opens a 30 s breaker for that process only, which in FPM is meaningless. With a shared cache, a failing flush anywhere opens it for everyone. That is the behaviour you want for outage protection, but it also means one bad deploy can silence telemetry across the fleet for 30 s at a time, and it means a cache eviction policy that drops breaker keys quietly disables your protection. Verify the keys survive your cache's TTL and eviction rules.

Retries resend a byte-identical body under the same batch id — but rejections derive a new one. If the collector returns validation_failed, those events are dropped and reported, and the remainder is resent under a derived batch id. If your downstream pipeline dedupes on batch id, expect two ids for one logical batch. Also: an empty idempotency key is refused outright, so never construct batches by hand with a blank id.

Three timeouts, three places to look. flushDeadlineMs (3 s) caps the whole flush; connectTimeoutMs (1 s) caps connection establishment; Retry-After from the server is honoured but bounded. A batch that silently never arrives is usually the flush deadline winning over the retry schedule — full-jitter backoff can consume the entire budget on the second attempt. If you need durable delivery, that is the signal to move to deliverPrepared() in a queue worker with a longer leash.

Consentless mode refuses identifiers. If you switch collection mode, identify() calls start being rejected. Audit those call sites before flipping the flag, and do not assume a caught rejection means the event was queued — the identifier is refused, the surrounding tracking may not be.

validation_failed events vanish by design. They are dropped and reported, not thrown. If nobody is reading the report, data loss is silent. Wire that report into your exception handler or log channel on day one.

Transport choice is not cosmetic. cURL and PHP streams behave differently around timeouts and connection reuse; PSR-18 gives you Guzzle's middleware (retry logging, request IDs) for free. Pick PSR-18 in Laravel — you almost certainly already have a configured client, and you want its instrumentation.

Long-lived workers. flush() on shutdown and destruction assumes a per-request lifecycle. Under Octane or a queue worker the instance may live far longer than a request, so buffers accumulate toward the 1000-event / 1 MiB ceiling and flush on an unpredictable schedule. Call flush() yourself at request end and after each job. flushOnShutdown exists as a seam — decide explicitly whether you want it on.

Unreadable document is reported, not thrown. Same story as validation failures: a malformed or missing flag document degrades you to whatever your fallback is, quietly. Always code a default per flag and assert in a health check that the document is non-empty.

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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource