zendframework/zenddiagnostics
ZendDiagnostics provides a library of ready-made health checks for PHP applications—verify database connections, filesystem permissions, disk space, PHP settings, and more. Use it standalone or with Zend Framework to monitor app health and catch issues early.
Architecture fit
zendframework/zenddiagnostics is a framework-agnostic diagnostic runner plus a library of small Check classes. Its contract is simple: register checks, run them, collect Result objects (Success/Warning/Failure), hand them to a Reporter (Json, Text, Xml, Console). That shape maps cleanly onto a health-check endpoint or an artisan command, but it is not a Laravel package: there is no service provider, no facade, no config publishing, and no container awareness. Any Laravel integration is glue code we write and own. The checks that matter most in a Laravel context (Redis, Memcached, PDO/Doctrine, disk, extensions, PHP version, HTTP service reachability) exist, but several are bound to Zend/Laminas components (zend-http, zend-db, zend-cache, Doctrine) rather than Laravel's own abstractions, so the framework-level value is mostly conceptual — a well-factored taxonomy of health checks — rather than reusable machinery.
Integration feasibility
Feasible in a day for a proof of concept: add the dependency, instantiate Runner, register a handful of checks, expose a /health route returning Reporter\Json output. Feasible in production is a different question, gated almost entirely by dependency resolution rather than code. Practical constraints:
zendframework/* namespace is superseded by laminas/*; Composer will happily install both trees, which is how dependency drift and duplicate-class surprises start.zend-http alongside Guzzle, zend-cache alongside Laravel's cache), inflating the vendor tree and the CVE surface for a feature that is fundamentally ~500 lines of probe logic.spatie/laravel-health, which is maintained, container-native, and covers the same check categories.Technical risk
| Risk | Likelihood | Impact | Note |
|---|---|---|---|
| PHP 8.x incompatibility / deprecations | High | High | Archived before PHP 8 GA; any fix is a fork we own |
| Unpatched security issue in transitive Zend deps | Medium | High | No upstream advisory channel |
| Dependency conflict with Laravel/Guzzle/Cache stack | Medium | Medium | Resolution failures or pinning pressure on core deps |
| Health probe false negatives → LB drains healthy nodes | Medium | High | Network-touching checks with no timeout policy |
| Silent bit-rot (checks reference dead protocols/APIs) | High | Low-Med | SecurityAdvisory, CouchDb/Mongo checks are stale |
| License | Low | Low | BSD-3-Clause is permissive and compatible |
Key questions
spatie/laravel-health or Laravel's native health route that this package fills?TPM recommendation: treat this as a design reference, not a dependency. Score 1.25 with an archived flag is a stop signal for production adoption in a Laravel stack; the package's durable contribution is the check taxonomy, which is cheap to reimplement on top of a maintained library.
Stack fit
Poor-to-neutral. Laravel's idioms — service container, config/*.php, Artisan, middleware, the Health route — have no counterparts in a 2019 Zend component. Everything is manual wiring: a service provider we author, a config array we translate into Runner::addCheck() calls, a controller returning Reporter\Json output, and a normalization layer mapping Zend Result objects to our API contract. The checks that operate on raw PHP (version, extensions, stream wrappers, directory permissions) port trivially; the ones bound to Zend/Doctrine services require adapters or replacement.
Migration path
spatie/laravel-health (or Laravel's native health route) for the runner/reporting shell, and port the specific checks we want. Estimated effort: 2–4 engineer-days for the common set (DB, Redis, disk, PHP version/extensions, queue backlog, scheduler heartbeat) versus 3–5 days plus permanent fork ownership for the Zend route.zendframework/zenddiagnostics → laminas/laminas-diagnostics to stay on a supported namespace and PHP 8; then, during the Laravel cutover, re-express the check set against the Laravel-native library. Do not carry the Zend namespace into the target stack — that is how a two-year tail of abandoned dependencies forms.composer why zendframework/zenddiagnostics, list registered checks, confirm which are wired into a live probe. Freeze, then replace on the next planned release.Compatibility
Verify before any spike: composer require zendframework/zenddiagnostics against the target PHP and Laravel version in a throwaway branch. Expect PHP constraint friction above 7.4 and possible conflicts on zend-http/zend-db against Guzzle and Laravel's DB layer. Any --ignore-platform-reqs or replace block is a red flag that should escalate to a "do not proceed". Also confirm which reporter formats are consumed downstream — if a monitoring vendor parses Reporter\Json, that schema becomes a contract we must preserve through any migration.
Sequencing
critical vs degraded distinction.Maintenance
The dominant cost. An archived package means we are the maintainers the moment we ship it: PHP minor-version bumps, CVE triage in transitive Zend dependencies, and any behavioral drift in the checks themselves. That is a permanent, low-frequency, high-urgency on-call obligation attached to a feature that provides no product differentiation. Contrast with a maintained alternative, where the obligation is a Composer bump.
Support
Community-only, and the community has moved on — the Zend Framework forums and issue tracker are effectively read-only, Stack Overflow answers are 2015–2018 vintage, and there is no security advisory feed. Internal ramp-up for a new engineer means reading the source, which is small and legible (a genuine strength), but there is no external escalation path. Any incident involving the health endpoint is a pure internal debugging exercise.
Scaling
The runner executes checks serially and synchronously. Health endpoints are probed by every load balancer, every orchestrator liveness/readiness probe, and every uptime monitor — often every 10–30 seconds per instance. Checks that perform network I/O (Redis, Memcached, PDO connect, HttpService, SecurityAdvisory) therefore add latency in the hot path and multiply across the fleet. At even modest instance counts this is a nontrivial request volume against dependencies that are also serving application traffic. Mitigations: cache results for a short TTL, split liveness (process-only, always fast) from readiness (dependency checks, cached), and enforce a hard per-check timeout. None of these are provided by the package; all are ours to build.
Failure modes
Warning rather than Failure unless the dependency is genuinely required for that instance to serve.SecurityAdvisory check calling a retired endpoint, or a Mongo/CouchDb check against a removed driver) → 500 on the health route → orchestrator restart loop.Ramp-up
Low for the API — the Runner/Check/Result/Reporter model is graspable in an hour and the check classes are short and readable, which is why it remains a decent teaching reference. Higher for the ecosystem: engineers must understand the Zend/Laminas split, why both namespaces may appear in composer.lock, and which checks are quietly bound to Zend services. Net: the team can be productive in a day, but the organizational ramp-up — establishing fork ownership, on-call expectations, and a dependency policy that prevents recurrence — is the real cost and should be scoped explicitly before any adoption decision.
How can I help you explore Laravel packages today?