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

Analyzer Laravel Package

graham-campbell/analyzer

Analyzer is a PHP package by Graham Campbell that checks whether referenced classes actually exist. It helps catch missing or mistyped class references, supports PHP 8.1-8.5, and integrates with PHPUnit 10-13 for test-time analysis.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. Analyzer is not a Laravel package in the conventional sense — no service provider, no config file, no facade, no Artisan command, no container bindings, no publishable assets. It is a dev-only static check that plugs into PHPUnit via an AnalysisTrait exposing four static hooks (getPaths(), getIgnored(), shouldAnalyzeFile(), provideFilesToCheck(), all static since v4.0). It parses PHP source with nikic/php-parser, resolves use statements, type hints, instantiations, and — since v2.0 — PHPDoc references through phpdocumentor/reflection-docblock/type-resolver, then asserts each referenced class actually loads. The minimalism is the value proposition: zero production runtime footprint, nothing added to the boot path, nothing to reason about during an incident. The correct mental model is a pre-test quality gate that runs inside the existing test suite, not an application dependency.

Integration feasibility. High on the happy path, low on the follow-through. Installation is one composer require --dev "graham-campbell/analyzer:^5.1" plus a test case that uses the trait and declares paths and ignores. The real cost is triage: the first run against a mature Laravel codebase will surface a large wave of findings, each requiring a judgment call — genuine defect versus legitimate dynamic reference. Schedule around triage and ignore-list governance, not around installation.

Technical risk.

  • Detection is syntactic, not semantic. Class names appearing only as strings are invisible: config/app.php providers and aliases arrays, $app->make('...'), Route::middleware('...'), morph maps, event/listener discovery, factory $model properties, queue payloads, Blade/Inertia component strings. This is a material gap because stale providers and facade aliases in config arrays are among the most common Laravel breakage classes. The tool under-delivers exactly where Laravel breaks most often.
  • False positives are the dominant operational hazard. class_alias(), conditionally-defined classes, generated or eval-produced classes, package-discovery artifacts absent from the dev autoloader, and docblocks referencing optional or upstream dependencies will fail the gate while runtime is fine. getIgnored() is the escape hatch, but every entry is a permanent suppression that needs an owner.
  • False confidence. A green pipeline does not mean class references are correct — only that statically-visible ones resolve. Teams reading the badge as "static analysis solved" will under-invest in PHPStan/Psalm.
  • Version coupling is intentional and recurring. Analyzer majors track PHPUnit majors (v5.1 = PHPUnit 10–13 / PHP 8.1–8.5; v4.x = PHPUnit 9–10; v3.1 = PHPUnit 7–9). Your PHPUnit upgrade cadence becomes an Analyzer upgrade, and vice versa — a recurring line item in every framework/test-stack modernization.
  • Weak adoption signals. Stars are unlisted and dependents are reported as 0, which contradicts any "proven at scale" framing. Treat social proof as unverified and decide on a pilot, not a badge.

Key questions to answer before committing.

  1. Of our production incidents attributable to bad class references in the last 6–12 months, what share would this have caught given the string-based blind spot? If low, the value case weakens considerably.
  2. Who owns the getIgnored() list, and what is the review bar for adding an entry?
  3. Does the tool resolve against the dev autoloader only — and are all first-party packages, optional integrations, and discovery-driven providers installed in the CI dev context?
  4. What is our PHPUnit major upgrade cadence, and who absorbs the corresponding Analyzer bump?
  5. Does our static stack (PHPStan/Psalm, IDE inspections, Larastan) already catch unresolved class references at equal or better coverage? If yes, this is a duplicate gate, not a new one.
  6. If the package were abandoned tomorrow, how fast could we fork or replace it? MIT license and small surface suggest quickly — confirm nothing release-critical depends on it without a fallback.

Integration Approach

Stack fit. Complementary, not competitive. PHPStan/Psalm reason about types, signatures, and control flow; Analyzer reasons only about existence. Position it as layer zero of the static quality stack — cheapest, fastest, narrowest — running before the heavier tools so trivial breakage fails in seconds rather than minutes. Natural Laravel targets: service providers, facades, policies, API resources, form requests, jobs, mailables, console commands, and the PHPDoc blocks that feed IDE completion and generated API docs. Keep it out of the production dependency tree and out of the application namespace.

Migration path. Net-new capability, so the migration is organizational: from manual review for class correctness to an automated gate. Run report-only for two to four weeks, collect findings into a spreadsheet, classify each as defect / false positive / accepted suppression, then flip to blocking. Do not make it blocking on day one — a red pipeline on the first PR destroys credibility before the team understands the signal.

Compatibility. Pin to ^5.1 and treat the PHPUnit major as the binding constraint: PHP 8.1–8.5 and PHPUnit 10–13 are the supported envelope. Anything on PHPUnit ≤9 or PHP <8.1 needs an older Analyzer major and should be treated as a separate support track, not a backport. Verify that nikic/php-parser and the phpdocumentor reflection stack in the dev tree resolve without conflicting with Larastan/PHPStan, which pull their own parser versions — Composer will usually converge, but confirm in a clean composer update --dry-run before rollout. The package is --dev only; make that explicit in the lockfile review so it never leaks into a production image.

Sequencing.

  1. Pilot in one high-churn Laravel repo (ideally one that has recently undergone a major refactor).
  2. Add the test case with paths scoped to app/, tests/, and first-party packages — exclude vendor/ and generated code (IDE helpers, compiled container, cached config).
  3. Run report-only; triage findings into a defect backlog versus an initial getIgnored() seed list.
  4. Fix high-signal defects; document each ignore entry with a reason and owner.
  5. Flip to blocking in CI on the pilot repo; measure noise for two sprints.
  6. Roll out repo-by-repo, with the ignore list inherited only where the codebase genuinely overlaps.
  7. Revisit at each PHPUnit major upgrade — budget the Analyzer bump as part of that ticket, not as an afterthought.

Operational Impact

Maintenance. Low ongoing cost in the steady state, with two recurring obligations: the ignore list (which accretes silently and must be pruned) and the PHPUnit-major co-upgrade. Mitigate the first by requiring an inline comment or a linked ticket for every suppression and by reviewing the list quarterly — an ignore list nobody reads becomes a permanent blind spot. Mitigate the second by keeping a single owner for the test-tooling stack.

Support. Graham Campbell is a well-known, long-tenured maintainer of the Laravel-ecosystem GrahamCampbell package family, with a documented changelog, releases, security policy, and an enterprise support path through Tidelift. That is better support posture than most single-maintainer packages. The counterweight is the bus factor: one maintainer, no dependents, no visible downstream validation. Budget the effort to fork (small, MIT-licensed surface) as the contingency, and decide in advance whether Tidelift is worth the subscription for the specific value of commercial escalation on a dev-only test dependency — usually it is not.

Scaling. Scales well mechanically: analysis is per-file, stateless, and parallelizes across CI shards as a separate PHPUnit test case. Runtime grows linearly with the number of files in the configured paths, which is why path scoping matters more than anything else — pointing it at a large app/ plus first-party packages is fine; pointing it at everything including generated code is not. The scaling problem is social, not technical: the bigger and older the codebase, the larger the initial finding wave and the more ignore entries accumulate. Each ignore entry reduces coverage in a way that is invisible on a dashboard.

Failure modes.

  • Noisy red builds from false positives — the most likely reason the team disables it. Prevented by the report-only ramp and by keeping the ignore list curated rather than convenient.
  • Silent under-coverage — a bloated ignore list or an over-narrow path set means the gate passes while real breakage ships. This is the more dangerous failure because it looks like success. Track ignore-list size and path coverage as health metrics, not just pass/fail.
  • Coverage gap on string-referenced classes — config providers/aliases, container make() strings, middleware aliases, morph maps. Explicitly out of scope; do not let the badge imply otherwise. Pair with a config-cache smoke test or a boot-time integration test to cover this class of breakage.
  • Autoloader false negatives in CI — optional or conditional dependencies not installed in the dev context will register as missing classes. Ensure CI installs the same dev dependency set as a developer workstation.
  • Version drift lockout — a PHPUnit upgrade lands, the Analyzer bump is deferred, the constraint conflict forces removal, and the gate quietly disappears. Sequence them in the same ticket.

Ramp-up. Roughly half a day for a competent Laravel engineer to wire up, run against a pilot repo, and produce a triaged finding list; one sprint of two-to-four-week report-only observation before enabling blocking; then an hour or two per repo thereafter. The genuine ramp-up cost is the first triage on a legacy codebase, which can be multi-day and should be staffed accordingly and framed as a defect-discovery exercise rather than tooling setup — because that is what it actually buys you.

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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource