hoa/zformat
Hoa\Zformat is a PHP library for defining and compiling format strings. It provides a grammar and compiler that transform custom format expressions into PHP code, making it easy to build extensible, reusable string formatting rules.
Architecture fit. hoa/zformat is a leaf utility: a standalone string-formatting engine that resolves typed and named placeholders in a template string, built in Hoa's house style (paired with hoa/consistency, hoa/exception, and the hoa:// protocol wrapper). It has no architectural role to play in a Laravel application. Every layer where you might reach for it — request validation messages, mail templates, log lines, API error payloads — already has a first-party answer: sprintf/vsprintf, strtr, Str::replaceArray, and the translator's :placeholder replacement. The honest framing is that this is a replacement candidate, not a complement. There is no seam in a Laravel app where adding it improves the design.
Integration feasibility. Mechanically straightforward: composer require hoa/zformat, namespace Hoa\Zformat, low collision risk. The friction is in what comes with it — Hoa's own autoloader bootstrap, the hoa:// stream wrapper registration, and two archived transitive dependencies. Whether that bootstrap coexists cleanly with Composer 2's optimized and --classmap-authoritative autoloaders is an empirical question, not a documented guarantee. Assume a half-day spike just to prove the wiring, and treat global-state registration at boot as a code-review flag.
Technical risk.
${var} interpolation, implicit nullable parameters, dynamic properties, deprecated regex modifiers).Hoa\Exceptions rather than graceful degradation — converting a formatting bug into a 500 on a user-facing path.Key questions.
sprintf + strtr + Str::replaceArray + translator placeholders demonstrably cannot express? If the answer is "typed conversion with named fallbacks," that is a ~50-line internal helper.error_reporting(E_ALL)?Stack fit: poor for new work. Laravel ships format interpolation in maintained, understood places — native sprintf/vsprintf for positional and typed tokens, strtr for named tokens, Str::replaceArray/Str::replaceFirst for ordered substitution, and the translator's :name replacement for user-facing strings. The make-versus-buy call here resolves to make: a first-party Formatter helper costing tens of lines, fully typed, IDE-navigable, static-analysis-clean, and owned by us.
Migration path — applicable only where the package is already present:
composer why hoa/zformat, grep for Hoa\Zformat, enumerate call sites, and classify each by feature actually used (typed placeholders, named arguments, defaults, escaping).%, non-scalar parameters, empty templates. This is the artifact that de-risks everything downstream.format(string $template, array $params): string) and bind call sites to that contract, not to Hoa's API. Behavior must be identical before anything else changes.sprintf/strtr (or symfony/string plus a thin named-token pass), flip the container binding behind a feature flag, and run both implementations against the golden suite for one release cycle.hoa:// wrapper, and Hoa's autoloader bootstrap from composer.json and any service provider. Verify no hoa/* packages remain in the lock file.Compatibility. Pin the exact version in composer.lock, install --prefer-dist, accept no version range. Run CI against the target PHP matrix with full deprecation reporting. Confirm the autoloader works under --classmap-authoritative and --optimize-autoloader, since Hoa's registration mechanism predates those modes.
Sequencing and effort. Inventory → characterization tests → wrapper → replacement → uninstall. Estimate 1–3 engineering days for a handful of call sites; roughly a week if Zformat is doing user-facing templating with edge-case fidelity requirements. The characterization tests are the critical path — everything else is mechanical.
Maintenance. Effectively zero upstream. Every future bug, PHP upgrade break, and security finding is ours to fix. "Leave it running" is not a strategy; it is the silent accrual of an unfunded liability with no expiry. The realistic options are fork-and-own (with a named maintainer and a review cadence) or replace. Choosing neither is choosing to be surprised later.
Support. No maintainer to escalate to, no advisory channel, no issue triage. The internal escalation path is "we patch it ourselves," and that sentence needs to be written into the decision record and accepted by someone with a title before the dependency is merged.
Scaling. Compute cost is trivial — one scan pass per format call, negligible at any realistic request volume. The scaling concern is organizational, not runtime: a bespoke format dialect that no other PHP project, IDE, linter, or static analyzer understands. Each additional call site deepens the vocabulary a new engineer must learn to read the codebase.
Failure modes.
Hoa\Exception on malformed templates, escalating a formatting defect into a 500 on a user-facing path.hoa:// stream wrapper and custom autoloader, which can collide with other packages or with authoritative classmap dumps in production builds.Ramp-up. Near-zero to call, disproportionately high to debug. The API surface is one method; the failure surface is an undocumented hand-written grammar carrying 2017-era PHP assumptions. Onboarding cost is dominated by the question "why does this exist," which is precisely the question a TPM should not leave for a future hire to rediscover.
Verdict: no-go for new adoption. Do not add hoa/zformat to a Laravel codebase; satisfy the need with native sprintf/strtr/Str::replaceArray behind a first-party helper that we own and can type. If it already exists transitively, time-box the wrapper-and-replace sequence above rather than committing to a fork. Re-open the decision only if a hard dependency on another Hoa library materializes — and in that case, treat Zformat as a vendored liability with a named owner, a documented exception, and a scheduled removal date.
How can I help you explore Laravel packages today?