Проверка PHP кода: инструменты и подходы

Раздел: Разработка на PHP -> Проверки в PHP

Основные методы проверки PHP кода

Как обеспечить максимальную надёжность типов и логики в PHP проекте?

Наиболее эффективным речением для комплексной проверки PHP кода является использование статического анализатора PHPStan на максимальном уровне. Он выявляет ошибки типов, несоответствия сигнатур, недостижимый код и многие другие проблемы без выполнения программы.


composer require --dev phpstan/phpstan
php vendor/bin/phpstan analyse src --level=max
  

проверка php кода (проверка php кода)

После установки и запуска анализатор выведет ошибки в консоль. Для интеграции в CI можно добавить в composer.json скрипт:


{
  "scripts": {
    "phpstan": "phpstan analyse src --level=max --memory-limit=512M"
  }
}
  

Пример вывода с ошибкой типа:

 ------ ----------------------------------------------------------------- 
  Line   src/Service/UserService.php
 ------ ----------------------------------------------------------------- 
  42     Cannot call method find() on mixed.
 ------ ----------------------------------------------------------------- 
  [ERROR] Found 1 error
  

Типичная ошибка: пропущенные аннотации типов (@param, @return). Решение: постепенно добавлять строгие типы и docblocks. Также может возникнуть проблема с ложными срабатываниями - для их подавления используйте @phpstan-ignore.

Как быстро проверить синтаксис PHP файла?

Встроенная утилита php -l (lint) проверяет синтаксис без выполнения кода. Это полезно для быстрой проверки перед коммитом.


php -l index.php
  

Пример успешного вывода:

No syntax errors detected in index.php
  

Если в файле есть синтаксическая ошибка:


PHP Parse error:  syntax error, unexpected '}' in index.php on line 10
  

Проблема: утилита не проверяет логические ошибки, несовместимость типов. Решение: использовать в сочетании с другими инструментами.

Как проверить код на соответствие стандарту PSR-12?

Инструмент PHP_CodeSniffer (phpcs) проверяет стиль кодирования. Он настраивается под стандарты PSR-1, PSR-12, Symfony и другие.


composer require --dev squizlabs/php_codesniffer
vendor/bin/phpcs --standard=PSR12 src/
  

Пример вывода с нарушениями:

FILE: src/Helper.php
----------------------------------------------------------------------
FOUND 2 ERRORS AFFECTING 2 LINES
----------------------------------------------------------------------
 3 | ERROR | [ ] Opening brace of a class must be on the line after the definition
 5 | ERROR | [ ] Line indented incorrectly; expected 4 spaces, found 2
----------------------------------------------------------------------
  

Возможные проблемы: ложные срабатывания при кастомных настройках. Решение: создать собственный конфигурационный файл phpcs.xml и исключить определённые правила.

Как проверить корректность работы функций с помощью модульных тестов?

PHPUnit - стандартный фреймворк для модульного тестирования. Тесты проверяют поведение функций и классов в изолированном окружении.


composer require --dev phpunit/phpunit
vendor/bin/phpunit tests/
  

Пример простого теста:


// tests/CalculatorTest.php
use PHPUnit\Framework\TestCase;

class CalculatorTest extends TestCase
{
    public function testAddition()
    {
        $calculator = new Calculator();
        $this->assertEquals(5, $calculator->add(2, 3));
    }
}
  

Результат выполнения:

PHPUnit 10.0.0 by Sebastian Bergmann.

.

Time: 00:00.001, Memory: 6.00 MB

OK (1 test, 1 assertion)
  

Типичная ошибка: тесты не изолированы друг от друга, общее состояние. Решение: использовать setUp() и tearDown() для сброса состояния, а также мок-объекты для внешних зависимостей.

Как выявить потенциальные уязвимости в PHP коде?

Статические анализаторы безопасности, такие как Progpilot или RIPS (ныне интегрированный в PHPStan через расширения), помогают найти SQL-инъекции, XSS и другие уязвимости.


composer require --dev designsecurity/progpilot
vendor/bin/progpilot analyse src/
  

Пример вывода предупреждения:

[WARNING] SQL injection found in src/UserController.php line 24: $query = "SELECT * FROM users WHERE id = $_GET[id]";
  

Проблема: много ложных срабатываний при динамическом формировании запросов. Решение: настраивать контекстные правила, использовать белые списки или проверять код вручную.

Как найти узкие места в производительности PHP скрипта?

Профилирование с помощью Xdebug и анализа его вывода через KCachegrind или Webgrind позволяет увидеть количество вызовов и время выполнения каждой функции.


# Включить профилирование в php.ini:
xdebug.mode=profile
xdebug.output_dir=/tmp/profiles

# После запуска скрипта:
php -d xdebug.mode=profile script.php
  

Результат - файл .cachegrind. Его можно открыть в KCachegrind:


kcachegrind /tmp/profiles/cachegrind.out.12345
  

Проблема: Xdebug замедляет выполнение скрипта, и профилирование может исказить реальную картину. Решение: использовать профилирование на отдельной тестовой среде с аналогичной нагрузкой.

Расширенные примеры проверки PHP кода

Ниже приведены более глубокие и нестандартные сценарии применения инструментов проверки.

Настройка PHPStan с кастомными правилами и уровнями

Конфигурация phpstan.neon позволяет тонко управлять проверками:

Пример

parameters:
    level: 9
    paths:
        - src
    excludePaths:
        - src/Legacy/*
    checkMissingIterableValueType: true
    reportMaybes: false
    treatPhpDocTypesAsCertain: false
    customRulesetUsed: true
    rules:
        - vendor/some/package/custom-rules/Rule.php

Затем запуск:

Пример

php vendor/bin/phpstan analyse --configuration phpstan.neon

Результат может содержать только ошибки, относящиеся к строгим типам и отсутствующим аннотациям:

 ------ ---------------------------------------------------------------- 
  Line   src/Service/Validator.php
 ------ ---------------------------------------------------------------- 
  15     Parameter $value of method Validator::validate() has no type specified.
 ------ ---------------------------------------------------------------- 

Использование PHP_CodeSniffer с автоматическим исправлением

Инструмент phpcbf автоматически исправляет многие нарушения стиля:

Пример

vendor/bin/phpcbf --standard=PSR12 src/ --no-patch

Пример до и после:

Пример

// До: неправильный отступ и скобки
class MyClass{
  public function test(){
    echo 'hi';
  }
}

// После phpcbf:
class MyClass
{
    public function test()
    {
        echo 'hi';
    }
}

Интеграция Psalm с GitHub Actions

Для постоянной проверки кода в CI используют Psalm. Пример workflow:

Пример

name: Psalm
on: [push]
jobs:
  psalm:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: shivammathur/setup-php@v2
        with:
          php-version: '8.2'
          tools: vimeo/psalm
      - run: psalm --show-info=true --output-format=github

В результате в pull request будут отображаться аннотации с ошибками прямо в изменённых строках.

Глубокое профилирование с Xdebug и Blackfire

Кроме KCachegrind, можно использовать Blackfire для профилирования в продакшене. Пример настройки:

Пример

# Установка Blackfire PHP extension
composer require blackfire/php-sdk

# Профилирование участка кода
$probe = new \Blackfire\Probe();
$probe->enable();
// код для профилирования
$probe->disable();
$output = $probe->getData();

Это даёт детальную информацию о времени выполнения и памяти для конкретного участка.

Нестандартный пример: проверка конфигурационных файлов на соответствие схеме

Для проектов, где PHP код читает YAML/JSON конфиги, можно использовать библиотеку justinrainbow/json-schema для валидации структуры:

Пример

use JsonSchema\Validator;

$schema = json_decode(file_get_contents('schema.json'));
$data = json_decode(file_get_contents('config.json'));

$validator = new Validator();
$validator->validate($data, $schema);

if (!$validator->isValid()) {
    foreach ($validator->getErrors() as $error) {
        echo sprintf("[%s] %s\n", $error['property'], $error['message']);
    }
}

Результат:

[database.host] The property host is required
[database.port] Integer value found, but a string is required

Проверка PHP кода - comments

En
проверка php кода (php)