Skip to content

Static Analysis

Laureano F. Lamonega edited this page Jul 17, 2026 · 1 revision

Static Analysis (PHPStan)

Antimonial is analyzed with PHPStan at --level=max with zero @phpstan-ignore comments. Every type issue is resolved through proper fixes — not suppression.

Running it

vendor/bin/phpstan analyse --level=max --no-progress src/

Expected output:

[OK] No errors

Configuration

phpstan.neon:

parameters:
    level: max
    paths:
        - src
    bootstrapFiles:
        - tests/_stubs/constants.php

Why bootstrapFiles?

ROOT_PATH is a constant defined by the front controller (public/index.php) at runtime. PHPStan cannot discover it from scanFiles alone, so it is defined in a stub that is executed during analysis via bootstrapFiles:

// tests/_stubs/constants.php
<?php
declare(strict_types=1);
define('ROOT_PATH', __DIR__);

The stub points at tests/_stubs/, which contains a minimal app/Routes/web.php so App::loadRoutes()'s require resolves without a require.fileNotFound error.

How each issue class was fixed

Issue Fix
new.static in Request::fromGlobals() Constructor changed privateprotected + @phpstan-consistent-constructor on the class
(string) $value widening in Filters Rewritten with match narrowing
mixed capture groups in Compiler callbacks Closures typed (array $m): string with /** @var array<int, string> $m */
array<string, mixed>|null param in View::render() Changed to array<string, mixed> $capturedVars = [] (matches native type)
array_pop null/always-false in ViewEngine Routed through popEvalState(): ?array helper with explicit return type
require.fileNotFound in App::loadRoutes() Resolved via ROOT_PATH stub constant

Clone this wiki locally