PHP codebases span decades of framework evolution – from procedural scripts to Laravel and Symfony. VibeRails reviews every file and finds the architectural debt that PHPStan and Psalm can't detect.
PHP codebases carry archaeological layers of the language's evolution. A project that started on PHP 5.2 might contain procedural scripts with global variables, early OOP classes with no type declarations, and modern PHP 8.x code using enums and named arguments – all in the same repository. Each era has different error handling conventions, different approaches to database access, and different assumptions about what the language enforces.
Framework migration debt is common. Many PHP projects started as custom MVC implementations or CodeIgniter applications and later adopted Laravel or Symfony for new features. The result is a hybrid codebase where some routes go through the framework's router and middleware stack, while others are served by legacy entry points that bypass security filters entirely. The inconsistency is not visible from any single file – it only emerges when you map all the request paths through the application.
SQL injection is a persistent risk in PHP codebases with mixed-era code. Modern framework code uses parameterised queries through Eloquent or Doctrine. But legacy modules that survived the framework migration often contain string-concatenated SQL that was written before prepared statements were standard practice. These older files are rarely touched, rarely tested, and rarely reviewed – which makes them the most likely place for security vulnerabilities to persist.
PHPStan, Psalm, and PHP_CodeSniffer are strong at catching type errors, coding standard violations, and some security patterns within individual files. But they struggle with the cross-file architectural reasoning that legacy PHP demands.
Consider a Laravel application where error handling varies by module. Newer controllers use
exception handlers and return structured JSON responses. Legacy controllers wrapped into the
framework use manual try/catch blocks that return mixed HTML and JSON. Some utility classes
return false on failure instead of throwing exceptions, and their callers do
not check the return value. PHPStan can flag a missing return type, but it cannot assess
whether the error handling strategy across the application is consistent or safe.
Autoloading inconsistencies are common in PHP projects that evolved from pre-Composer code.
Some classes follow PSR-4, others use custom autoloaders, and a few are loaded via explicit
require_once statements. When the codebase mixes strategies, static analysis
tools produce false negatives because they cannot resolve all class references.
WordPress plugin codebases present their own challenges. Global state, hook priority conflicts, and the absence of dependency injection create tightly coupled code where changing one function can break behaviour in an unrelated plugin. Static analysis tools designed for framework code lack the context to reason about WordPress's hook-based architecture.
VibeRails performs a full-codebase scan using frontier large language models. Every PHP file, configuration file, Composer manifest, migration, and template is analysed – not just recent diffs, but the entire project including tests, deployment scripts, and legacy modules.
For PHP code specifically, the AI reasons about:
mysql_* and each(), missing strict types declarationsfalse, unchecked return values, bare catch (\Exception $e) blocks that swallow errorsrequire_once patterns that mask dependency issues, namespace mismatches between file paths and class declarations$wpdb prepared statementsEach finding includes the file path, line range, severity level, category, and a description with suggested remediation. The structured output turns a decades-old PHP codebase into an organised inventory of improvements prioritised by risk.
PHP codebases contain patterns that are genuinely ambiguous. Is that global variable in the
WordPress plugin intentional shared state, or a scoping mistake? Is the legacy
mysql_query call actually reachable, or is it dead code behind an abandoned
route?
VibeRails supports running reviews with two different AI backends – Claude Code and Codex CLI – in sequence. The first pass discovers issues, the second verifies them using a different model architecture. When both models flag the same SQL injection path or error handling inconsistency, confidence is high. Disagreements highlight areas where closer human inspection during triage is warranted.
After triaging findings, VibeRails can dispatch AI agents to implement fixes directly in your local repository. For PHP projects, this typically means converting string-concatenated SQL to parameterised queries, adding type declarations to untyped functions, replacing deprecated function calls with modern equivalents, and standardising error handling across modules.
Each fix is generated as a local code change you can inspect, test, and commit or discard. The AI works within the conventions of the existing codebase, matching the project's framework version, coding standard, and directory structure.
VibeRails runs as a desktop app with a BYOK model – it orchestrates Claude Code or Codex CLI installations you already have. No code is uploaded to VibeRails servers. AI analysis is sent directly to the provider you configured, billed to your existing subscription. Per-developer plans: $19/month (cancel anytime) or $299 lifetime. The free tier gives 5 issues per session to evaluate the workflow.
Tell us about your team and rollout goals. We will reply with a concrete launch plan.