class

Analyzer::Php::Slim

Inherits Analyzer::Php::PhpEngine < FileScanEngine < Analyzer < FileHelper < Reference < Object

Constants

FOREIGN_ROUTE_COLLECTORS = Set {"routes", "router", "route", "builder"}

Cheap pre-filter: avoid heavy regex work on files that clearly aren't Slim. Any file that reaches this analyzer via detection is usually in a Slim project, but project-wide scans still feed unrelated PHP here. Route-collector handles that belong to a different PHP framework by convention: $routes is CodeIgniter 4 and CakePHP, $builder is CakePHP's RouteBuilder, $router is Lumen. Slim's own docs and skeleton use $app and $group throughout.

This only gates the marker-less fallback below. Every PHP analyzer is fed every .php file in the scan, so in a repo holding more than one PHP framework that fallback read $routes->get('users/(:num)', …) out of CodeIgniter's app/Config/Routes.php and $builder->get('/status', …) out of CakePHP's config/routes.php, and emitted both as Slim routes. A genuine Slim file naming Slim\ keeps working regardless of what it calls its variables.

MEZZIO_MARKER_RE = /Mezzio\\/

Mezzio registers its programmatic routes on $app->get('/x', Handler::class) — the same expression Slim uses — so Slim read Mezzio's route table as its own. Mezzio\ is the one unambiguous marker: a Mezzio application names it, and Slim never does.

Laminas\ deliberately isn't on this list. Slim apps pull in Laminas\Diactoros for PSR-7 all the time, so excluding on it would drop their routes.

PARAM_PATTERNS = [{/\$args\s*\[\s*['"]([^'"]+)['"]\s*\]/, "path"}, {/->getQueryParams\s*\(\s*\)\s*\[\s*['"]([^'"]+)['"]\s*\]/, "query"}, {/->getParsedBody\s*\(\s*\)\s*\[\s*['"]([^'"]+)['"]\s*\]/, "form"}, {/->getHeaderLine\s*\(\s*['"]([^'"]+)['"]\s*\)/, "header"}, {/->getHeader\s*\(\s*['"]([^'"]+)['"]\s*\)/, "header"}, {/->getCookieParams\s*\(\s*\)\s*\[\s*['"]([^'"]+)['"]\s*\]/, "cookie"}]
RELEVANCE_MARKER_RE = /Slim\\|SlimFramework|AppFactory|RouteCollectorProxy/

Precompiled once at load: these four markers used to be four separate String#includes? scans of the whole file ORed together. Crystal's String#includes? is measurably slower than a single precompiled Regex#matches? call, and this runs on every .php file fed into the analyzer during a project-wide scan.

VERB_CALL_RECEIVER_RE = /\$(\w+)->(?:get|post|put|patch|delete|options|head|map|group)\s*\(/i

Class methods

tech_name
Source

Instance methods

analyze_file(path : String) : Array(Endpoint)
Source
tech

Instance-side view of the same declaration. The per-file rescues live on this base class, which has no way to name the analyzer that is running inside them, so a skipped file could not be attributed to a tech. Deriving it from analyzer_for keeps the name written exactly once.

Source