simplesamlphp/assert
A fork of webmozart/assert that lets every assertion throw a custom exception via an extra parameter, falling back to AssertionFailedException. It also adds XML/SAML2-specific assertions for SimpleSAMLphp projects.
What it actually is. simplesamlphp/assert is a thin fork/wrapper of webmozart/assert (~1 class + __callStatic proxy) that does two things: (1) lets every upstream assertion take an optional Throwable so failures raise a domain-specific exception instead of a generic InvalidArgumentException, and (2) adds SAML/XML-oriented assertions (validDateTime, validURI, validQName, validHexBinary, etc.) plus a default AssertionFailedException extending UnexpectedValueException. It is not a Laravel package: no service provider, no config, no facade, no validation rule objects, no ValidationException integration. Treat claims of "Laravel-native" integration in the supplied notes as aspirational rather than shipped functionality.
Architecture fit. Framework-agnostic PHP guard clauses — a reasonable fit for the domain/service layer of a Laravel app where you want invariant enforcement close to the computation and typed exceptions bubbling to an application-level handler. Poor fit as a replacement for Laravel's Validator on user-facing input, because it throws immediately on the first failure and bypasses the error-bag, localization, and 422 ValidationException contract that Inertia/Livewire/API clients expect.
Integration feasibility. Composer-only, zero config, so installation is trivial. The real friction is dependency topology: webmozart/assert is a transitive dependency of much of the Symfony ecosystem, so version pinning needs checking against the existing lockfile; the README's "extra $exception parameter" pattern also means the public API is behind __callStatic, which typically degrades IDE completion and PHPStan inference — confirm whether stubs/annotations ship before you bank on "PHPStan enabled" as a quality signal.
Key technical risks.
AssertionFailedException / UnexpectedValueException do not map to Laravel's 422 flow by default; without an explicit handler mapping you will ship 500s for user input errors.Assert::extend(), Assert::custom()) and show enum() with an array argument rather than the expected enum-class signature. Anything built from those examples will fail at runtime; re-verify every pattern against vendor/simplesamlphp/assert/src before sprint planning.Key questions for the maintainer/team. Is the added value over plain webmozart/assert (a custom exception class + 12 SAML assertions) worth a new dependency for a non-SAML product? Can we get the same outcome with a project-local Assert facade over webmozart and a domain exception? Who owns upgrades — us or upstream?
Stack fit. Compatible with any Laravel 9+ / PHP 8.0+ application at the Composer level; the enum-support improvements in v1.5.0 target PHP 8.1+ enum ergonomics. It slots in cleanly as a guard layer, not a validation layer: service constructors, value-object factories, repository inputs, config bootstrapping, queue payload hydration. Keep Laravel FormRequest/Validator for HTTP input; use Assert behind that boundary.
Migration path. Do not attempt a codebase-wide sweep. Sequence:
AssertionFailedException → 400/422 and a production-safe message strategy (app.debug gating, or wrapping assertions with context-only messages). Without this, adoption converts latent validation errors into 500s.$exception parameter, a ~30-line internal wrapper over webmozart/assert removes the LGPL question and the bus-factor risk entirely. If the XML/SAML assertion set is load-bearing, adopt the package.Compatibility. Confirm PHP constraint vs. your minimum supported version, PHPStan/Psalm baseline impact (static proxies), and PHPUnit expectations — assertion failures throw, so tests must assert on the exception type you configured, not a single shared type across the codebase.
Sequencing with the roadmap. Only worth pulling forward if a near-term deliverable touches SAML/OIDC, XML signature validation, or strict RFC-compliant identifier checks; otherwise this is opportunistic hygiene, not roadmap work.
Maintenance. Tiny surface area, so upgrade risk per release is low; the cost is attention, not code. Budget a recurring (quarterly) dependency review: upstream webmozart/assert major bumps propagate, and v1.5.0's stricter regex behaviour (rejecting trailing newlines) is a silent behavioural change that can break previously passing inputs — pin the version and read release notes rather than floating ^1.5.
Support. No commercial support, no SLA, no issue-triage guarantee from a 7-star project. Internal ownership must be explicit: name a DBA/tech lead accountable for the wrapper, its exception mapping, and its eventual replacement. Document the wrapper's semantics in the team's own ADR — the README will not answer "which exception do I throw here?"
Scaling. Negligible runtime cost per assertion (a comparison plus optional exception construction); the cost is exception throw paths in hot loops, which should be avoided as a control-flow mechanism. No I/O, no state, no cache surface — horizontally scales with the app by construction. Static calls are also awkward to mock, so favour asserting on behaviour rather than stubbing Assert in tests.
Failure modes to instrument.
AssertionFailedException volume and route.webmozart/assert version collision) → CI must run composer update --dry-run against the full matrix, not just the local lock.App\Support\Assert delegating to the package) so a swap to webmozart or native checks is a one-file change.Ramp-up. Low: an engineer familiar with webmozart/assert is productive in under an hour, and PHPStan/language-server hints cover most of the API. The realistic onboarding cost is convention, not API — new hires will default to Laravel's Validator and need the "guards vs. validation" boundary written down. Budget half a day of documentation and one brown-bag session; do not budget training on the supplied snippets, as several are incorrect.
How can I help you explore Laravel packages today?