fangstar/php-validator
A lightweight, framework-agnostic PHP validation library with a familiar Laravel-style rule syntax. Validate arrays and request data using built-in rules, custom messages, and nested fields, plus support for custom validators—no framework required.
Architecture fit. fangstar/php-validator is a framework-agnostic PHP parameter-validation component, not a Laravel package. It ships no ServiceProvider, no Facade, no ValidatorFactory implementation, and no bridge to Illuminate\Contracts\Validation. In a Laravel codebase it does not replace the framework validator — it runs alongside it. That creates a second, parallel validation path: two rule syntaxes, two error-message shapes, two localization stories, and two places a developer must remember to look when a request is rejected. For a TPM, that is the central architectural finding: adoption buys a rule DSL we don't have, and pays for it with a permanently bifurcated validation layer.
Integration feasibility. Mechanically trivial — a Composer require and a thin adapter. Idiomatically expensive. To be acceptable it must be reconciled with FormRequests, the exception handler's 422/JSON contract, API error envelopes, and lang/ files. That reconciliation work is larger than the library itself and is the real cost line.
Technical risk. High, concentrated in maintenance rather than correctness:
php version constraint, no scalar/return types, no strict types, and likely reliance on constructs removed in PHP 8 (each(), create_function, curly-brace string offsets) or dynamic-property deprecations. Modernization is not a config change; it is an edit-and-test cycle.Key questions to resolve before any code is written.
Rule:: objects, or a custom Rule class cannot express in under 50 lines?Verdict to carry into the gate: the only defensible reason to adopt is a named, concrete validation pattern that Laravel genuinely cannot express. Absent that, this is a reference implementation to read, not a dependency to install.
Stack fit. Poor as a primary validator, acceptable as an isolated component. Laravel's built-in validator already covers the overwhelming majority of parameter-validation needs — presence/nullable/type rules, nested array validation, custom Rule objects, conditional rules, localization, and a mature 422 contract. Layering a 2016 standalone validator on top trades ecosystem support for syntactic novelty.
Migration path (if the evaluation gate passes).
ValidationService contract and implement it with a Laravel-backed driver first. Any third-party engine becomes one driver behind that seam — swappable, mockable, and removable in a single PR.MessageBag/ValidationException so downstream error handling, logging, and API envelopes remain single-sourced.Compatibility work required before merge. Add an explicit php constraint in our wrapper's composer.json, run PHPStan at a level comparable to the rest of the codebase, and run Rector against the fork to surface PHP 8 incompatibilities early. Without a test suite, we author characterization tests ourselves — these become the fork's real safety net.
Sequencing.
| Phase | Activity | Exit criteria | Effort |
|---|---|---|---|
| 0 | Spike: fork, Rector, PHPStan, write characterization tests | Library runs clean on target PHP; semantics understood | 1–2 days |
| 1 | Decision gate: does it beat a custom Rule class? |
Named requirement satisfied, or stop | 0.5 day |
| 2 | Adapter + contract tests behind ValidationService |
Laravel driver and library driver both pass | 2–3 days |
| 3 | Shadow mode on 1–2 endpoints, diff outcomes vs. existing validation | Zero unexplained divergences over a defined sample | 3–5 days |
| 4 | Promote to one low-risk endpoint, monitor | No 500s, error envelope parity | 1 week soak |
| 5 | Hold. Do not expand until fork ownership is staffed | Owner assigned | — |
Phase 1 is the cheap kill switch. Most teams should take it.
Maintenance. This is the dominant cost and it is structural, not incidental. Upstream is dormant since November 2016; adoption means we become the maintainer of record. Budget a standing ~0.1 FTE for fork upkeep, PHP-version churn, and framework-upgrade compatibility, indefinitely. Every future PHP or Laravel major becomes a small project rather than a composer update.
Support. No vendor, no SLA, no security disclosure channel, sparse Chinese-language documentation, and effectively no community to escalate to. Issue triage, root-cause analysis, and patches all fall to the internal team. Onboarding material must be written in-house because there is nothing to link to.
Scaling. Throughput is a non-issue — parameter validation is CPU-trivial relative to I/O and will not be a bottleneck at any realistic request volume. The scaling risk is organizational: the set of engineers who understand the rule semantics and the fork's deviations stays small, and that knowledge does not scale with headcount.
Failure modes to instrument for.
composer audit and advisories will never report on this package because no one is filing against it. Absence of alerts is not absence of risk, and the team loses the early-warning signal it correctly relies on for mainstream dependencies.Ramp-up. Low for basic use — the public API surface is small and the concepts are familiar to anyone who has written validators. Higher for the parts that matter: understanding the exact rule semantics, the parser's quirks, and the fork's divergences from Laravel behavior. Realistic ramp is well under a day for productive use, but "trusted to modify the fork safely" is a single-person capability until deliberately spread.
Bottom line. As a dependency, this package's operational profile is unfavorable: dormant upstream, no consumers, no safety net, and a cost structure that converts a one-line composer require into permanent internal ownership. As a design reference for teams wanting a compact rule-DSL validator, it is cheap to read and free of obligation. The TPM recommendation is to route the underlying need to Laravel's validator plus custom Rule classes, and revisit only if Phase 1 surfaces a validation requirement those cannot express.
How can I help you explore Laravel packages today?