Tutorials Logic, IN info@tutorialslogic.com

PHP Code Quality and Static Analysis with PSR-12, PHPStan, and Automated Gates

Automated Feedback

Formatting, static analysis, and tests answer different questions. A formatter makes code mechanically consistent, PHPStan reasons about types and control flow without running the application, and tests execute selected behavior against examples and boundaries.

After this lesson, you can install a static analyzer as a development dependency, run it against owned source paths, raise strictness gradually, and combine lint, style, analysis, and tests into one repeatable project command.

Quality Layers

Check Finds Does Not Prove
php -l Parse errors Correct behavior
Formatter or PHPCS Style differences Type safety
PHPStan Type and flow inconsistencies Database or HTTP behavior
PHPUnit Executed assertions Every untested path

PSR-12 Style

PSR-12 provides shared formatting expectations that reduce review noise between projects. Enforce style with a tool rather than spending review time on spaces and braces. Keep generated files and vendor dependencies outside the project style target.

  • Declare strict types before the namespace when the project adopts it.
  • Keep imports organized and remove unused names.
  • Use one consistent brace and indentation policy.
  • Let the formatter make mechanical changes; review semantic changes separately.

PHPStan Start

Install development tools through Composer so the lock file pins the team version. Analyze application source and tests, not vendor code.

Install and Analyze

Install and Analyze
composer require --dev phpstan/phpstan
vendor/bin/phpstan analyse src tests --level=6

Use vendor\bin\phpstan on Windows Command Prompt when forward-slash invocation is unavailable.

Type Precision

Native types describe runtime contracts; PHPDoc can refine collection shapes and generics for analysis. Prefer changing vague application design over adding a broad ignore rule.

Describe Record Shape

Describe Record Shape
<?php
/** @param list<array{id:int, title:string}> $tasks */
function taskTitles(array $tasks): array
{
    return array_map(
        static fn (array $task): string => $task['title'],
        $tasks,
    );
}

The shape lets analysis detect a missing title key or an unexpected value type before that path executes.

Baseline Discipline

A baseline can record existing findings during gradual adoption, but new code should not add new ignored failures. Every direct suppression should name a narrow tool identifier and include a reason the team can remove later.

One Quality Command

Expose the local checks as Composer scripts and run the same command in continuous integration. Fail early on syntax, then style, static analysis, unit tests, and boundary tests.

Composer Quality Scripts

Composer Quality Scripts
{
  "scripts": {
    "analyse": "phpstan analyse src tests --level=6",
    "test": "phpunit",
    "quality": ["@analyse", "@test"]
  }
}

Choose the Right Check

0 of 2 checked

Q1. Can static analysis prove a real database accepts a query?

Q2. Why pin tools in Composer?

Static Analysis Boundary

  • Suppressing the signal

    Avoid broad baselines or ignore rules that hide new defects. Scope each suppression to a known case, document why it is sound, and remove it when the code changes.

Try this next

Create a Quality Gate

0 of 2 completed

  1. Install PHPStan, start at a useful level, classify every finding, and fix one root type problem without a broad ignore.
  2. Create one Composer script that runs the same analysis and tests in both environments.
Browse Free Tutorials

Explore 500+ free tutorials across 20+ languages and frameworks.