denzyl/phanalist

Performant static analyzer for PHP, which is extremely easy to use. It helps you catch common mistakes in your PHP code.

Installs: 17 680

Dependents: 0

Suggesters: 0

Security: 0

Stars: 145

Watchers: 4

Forks: 6

Open Issues: 3

Language:Rust

pkg:composer/denzyl/phanalist

v0.1.22 2024-05-17 20:28 UTC

README

Crates.io License: MIT CI

Performant static analyzer for PHP, written in Rust. Catches common mistakes and enforces best practices with zero configuration required.

✨ Features

  • 🚀 Fast — built in Rust, analyzes large codebases in seconds
  • 🔍 14 built-in rules — covering complexity, style, design patterns, and more
  • ⚙️ Zero config to start — works out of the box, configure only what you need
  • 📄 Multiple output formatstext, json, and sarif (for CI pipelines)
  • 🔌 Extensible — adding a custom rule takes minutes

Installation

The simplest way to install Phanalist is to use the installation script:

curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/denzyldick/phanalist/main/bin/init.sh | sh

It will automatically download the executable for your platform:

$ ~/phanalist -V
phanalist 1.0.0

There are also multiple other installation options.

Usage

To analyze your project sources, run:

~/phanalist

Example

Example

On the first run phanalist.yaml will be created with the default configuration and reused on all subsequent runs.

Additional CLI flags:

Flag Description Default
--config Path to configuration file ./phanalist.yaml
--src Path to project sources ./src
--output-format Output format: text, json, sarif text
--summary-only Show only violation counts per rule
--quiet Suppress all output

Configuration

enabled_rules: []   # empty = all rules active
disable_rules: []
rules:
  E0007:
    check_constructor: true
    max_parameters: 5
  E0009:
    max_complexity: 10
  E0010:
    max_paths: 200
  E0012:
    include_namespaces:
      - "App\\Service\\"
      - "App\\Controller\\"
    exclude_namespaces: []
  • enabled_rules — whitelist of rules to run (empty = all)
  • disable_rules — rules to skip
  • rules — per-rule configuration options

Rules

Code Name Options
E0000 Example rule
E0001 Opening tag position
E0002 Empty catch
E0003 Method modifiers
E0004 Uppercase constants
E0005 Capitalized class name
E0006 Property modifiers
E0007 Method parameters count check_constructor: true, max_parameters: 5
E0008 Return type signature
E0009 Cyclomatic complexity max_complexity: 10
E0010 Npath complexity max_paths: 200
E0011 Detect error suppression symbol (@)
E0012 Service compatibility with Shared Memory Model include_namespaces, exclude_namespaces, reset_interfaces
E0013 Private method not being used
E0014 Law of Demeter

Adding a new rule is straightforward — this tutorial explains how.

Articles

Read a series of chapters on https://dev.to/denzyldick to understand the project's internals — a great, easy-to-read introduction.

  1. Write your own static analyzer for PHP.
  2. How I made it impossible to write spaghetti code.
  3. Detecting spaghetti code in AST of a PHP source code.
  4. Getting Symfony app ready for Swoole, RoadRunner, and FrankenPHP (no AI involved).
  5. Improve your CI output
  6. Why using unserialize in PHP is a bad idea