Complete reference for Phan v6 command-line flags, options, and usage patterns.
# Basic analysis
phan
# Analysis with config file
phan --config-file .phan/config.php
# No config file (analyze provided files only)
phan -n file1.php file2.php
# Incremental analysis (faster re-runs)
phan --incremental
# Force full re-analysis
phan --force-full-analysis
# Save baseline for issue tracking
phan --save-baseline .phan/.baseline.php
# Analyze against baseline
phan --load-baseline .phan/.baseline.phpSpecify the configuration file to use.
phan --config-file .phan/config.php
phan -c custom-config.phpNew in V6: When used with file arguments, limits analysis to just the provided files (ignores the rest of the project).
# Quick analysis of specific files
phan -n src/User.php src/Product.php
# Without -n, would analyze entire configured project
phan src/User.php # Analyzes entire projectThis is useful for:
- Quick checks during development
- IDE integration
- Focused analysis of specific modules
Override the project root directory.
phan --project-root-directory /path/to/projectDramatically speeds up re-runs by only analyzing changed files.
Enable incremental analysis mode.
# First run - full analysis
phan --incremental
# Creates .phan/.phan-incremental.php manifest
# Subsequent runs - only changed files
phan --incremental
# Much faster!New in V6: Previously -i was an alias for --ignore-undeclared. Now it's for --incremental.
Disable incremental analysis (useful if enabled in config).
phan --no-incrementalForce a complete re-analysis, ignoring the incremental manifest.
# After major changes or dependency updates
phan --force-full-analysisNew in V6: Analyze only the current subdirectory with better performance.
cd src/Module/A
phan --subdirectory-onlyBenefits:
- Faster focused analysis
- Still loads dependency information from full project
- Useful for large monorepos
Track issues over time without suppressing them in code.
Generate or update a baseline file.
# Create baseline
phan --save-baseline .phan/.baseline.php
# Update baseline after fixes
phan --save-baseline .phan/.baseline.phpThe baseline records all current issues. On subsequent runs:
- Only NEW issues are reported
- Known issues are suppressed automatically
- Allows gradual improvement over time
Use a previously saved baseline.
phan --load-baseline .phan/.baseline.phpTypically configured in config.php:
return [
'load_baseline' => '.phan/.baseline.php',
];Only save suppressions for files not yet analyzed.
phan --save-baseline-in-missing-files-only .phan/.baseline.phpLimit array elements per level before summarization.
# Default: 256
phan --ast-trim-max-elements-per-level 512Lower values = less memory, fewer accurate types Higher values = more memory, better accuracy
Limit total elements in nested arrays.
# Default: 512
phan --ast-trim-max-total-elements 1024Limit union type combinations.
# Default: 1024
phan --max-union-type-set-size 2048When exceeded, types are intelligently merged to prevent runaway growth.
Print a report of where a run spent its time to stderr when Phan exits.
phan --dump-phase-timings 2> timings.txtEach line is prefixed with phan-timings. The report shows, for every phase
(config, parse, class/function/method analysis, ordering, fork, waiting on
workers, result collection, dead code, finalize, display), the wall clock time,
user and system CPU time, RSS, high-water mark and Zend peak memory. It also
prints per-file parse and analysis time percentiles, the 25 slowest files,
totals per top-level directory, and counts of user classes, functions,
declared methods and inherited method clones.
With --processes N each worker reports its own analysis, finalize and emit
times, its private memory (Private_Dirty/Pss) and how long its teardown
took; the parent adds the load imbalance between workers, the serial fraction
of the run and the worker efficiency.
Collection is off by default, costs nothing when off and does not change
analysis results. While enabled, $GLOBALS['__phase'] holds the current phase
name so that sampling profilers can attribute samples to phases
(e.g. phpspy -g globals.__phase).
Write the same measurements as --dump-phase-timings to <path> as JSON
(schema phan-phase-timings/1), for benchmark scripts and dashboards.
phan --phase-timings-json timings.json
# Both at once
phan --dump-phase-timings --phase-timings-json timings.jsonRelative paths are resolved against the working directory (after
--project-root-directory is applied). Durations are seconds (*_s) and
memory is megabytes (*_mb); phases is a list in execution order.
Number of parallel analysis processes.
# Use 4 processes
phan -j 4
# Use optimal for your CPU
phan -j $(nproc)Default: number of CPU cores
Specify output format.
phan -o text # Human-readable (default)
phan -o json # JSON output
phan -o csv # CSV format
phan -o checkstyle # Checkstyle format (for CI)Write output to file instead of stdout.
phan -f analysis-results.txt
phan -o json -f results.jsonEnable colored output.
phan --colorDisable colored output.
phan --no-colorOnly show errors, no summary.
phan -qSpecify how to handle specific issue types.
# Suppress specific issues
phan --issue-handlers PhanUnreferencedPublicMethod:suppress
# Warn on others
phan --issue-handlers PhanDeprecatedFunction:warnSuppress a specific issue type globally.
phan --suppress-issue-type PhanUnreferencedPublicMethodShow suggested fixes (if available).
phan --show-suggestionsRun analysis twice to catch more issues.
phan --analyze-twiceSlower but more thorough. Useful for complex codebases.
Don't use phpstan baseline (if configured).
phan --skip-phpstan-baselineSet the PHP version to analyze for.
phan --target-php-version 8.2
phan --target-php-version 7.4Default: version from config or current PHP version
Phan v6: Specify minimum target version.
phan --minimum-target-php-version 8.0Generate a .phan/config.php interactively, based on your project's composer.json and directory structure.
./vendor/bin/phan --initRelated flags for non-interactive initialization:
| Flag | Description |
|---|---|
--init-level <1-5> |
Strictness level: 1 = most lenient, 5 = strictest. Default: 3 |
--init-analyze-dir <DIR> |
Directory to analyze (in addition to those from composer.json) |
--init-analyze-file <FILE> |
Individual file to analyze |
--init-no-composer |
Don't use composer.json to detect directories |
--init-overwrite |
Overwrite an existing .phan/config.php |
Example for a project without Composer:
phan --init --init-no-composer --init-analyze-dir src --init-level 3Automatically apply fixes for issues that support it. Currently supported by several built-in plugins including PHPDocRedundantPlugin, PHPDocToRealTypesPlugin, and WhitespacePlugin.
phan --automatic-fix --force-polyfill-parserRequires --force-polyfill-parser (or --force-polyfill-parser-with-original-tokens) because the polyfill parser provides the token-level source location information needed to compute byte offsets for edits.
Note: Make a backup or commit your code before running
--automatic-fix. Review the changes withgit diffbefore committing.
Force use of the microsoft/tolerant-php-parser fallback instead of the php-ast extension. Required for --automatic-fix.
phan --force-polyfill-parser --automatic-fixLike --force-polyfill-parser, but also preserves original token stream for more precise source location. Required by some --automatic-fix plugins.
Use the polyfill parser only if the php-ast extension is not available. Useful for environments where php-ast may or may not be installed.
Load specific plugins.
phan --load-plugins PregRegexPlugin,PHPDocPluginMultiple plugins separated by comma.
Breaking Change: The -i flag is now --incremental (not --ignore-undeclared).
# Old (v5)
phan -i # Ignored undeclared variables
# New (v6)
phan -i # Enables incremental analysisRun Phan in daemon mode.
# Start daemon
phan --daemon
# Request analysis
phan --daemon-requestFor long-running processes with faster subsequent requests.
See [[Using-Phan-Daemon-Mode]] for details.
Display Phan version.
phan --versionDisplay help message.
phan --helpDisplay extended help with all options.
phan --extended-help# Analyze specific file(s) without full project analysis
phan -n src/User.php# Fast analysis for IDE/editor
phan -n "$FILE_PATH" --output-mode json# Incremental analysis in CI
phan --incremental \
--output-mode checkstyle \
--output-file reports/phan.xml# Create baseline
phan --save-baseline .phan/.baseline.php
# Run with baseline (only NEW issues reported)
phan --load-baseline .phan/.baseline.php
# Fix some issues, then update baseline
phan --save-baseline .phan/.baseline.php# For large codebases
phan --incremental \
--processes 8 \
--ast-trim-max-elements-per-level 512 \
--max-union-type-set-size 2048# Use all CPU cores
phan -j $(nproc)
# Specific number of processes
phan -j 4# 0 - Analysis successful, no issues
phan; echo $? # 0
# 1 - Analysis found issues
phan; echo $? # 1
# 2 - Error during analysis
phan; echo $? # 2Use in scripts:
#!/bin/bash
phan
if [ $? -eq 0 ]; then
echo "Analysis passed"
else
echo "Analysis found issues"
exit 1
fiAllow missing parameter type hints (v5 behavior).
PHAN_ALLOW_MISSING_PARAM_TYPE=1 phanDisable XDebug for performance.
PHAN_DISABLE_XDEBUG=1 phanSince 6.0.8, the analysis workers of --processes N terminate without running PHP's shutdown sequence once they have sent their results to the parent, which avoids copying the memory pages they share with the parent. Set this to keep the regular exit(), e.g. when debugging workers. It is also kept when a profiler, xdebug or pcov is active.
PHAN_DISABLE_FAST_EXIT=1 phan -j 4Since 6.0.8, the checks that only emit issues about the declaration of a function or method are skipped when it is declared in a file excluded from analysis (such as vendor/), because those issues are discarded anyway. Set this to run them regardless (the previous behavior).
PHAN_ANALYZE_EXCLUDED_METHODS=1 phanSince 6.0.8, the declaration analysis of a method that a class inherits is replayed from the analysis of the method it was copied from, instead of being repeated. Set this to analyze every inherited method.
PHAN_DISABLE_CLONE_REPLAY=1 phanFor developing Phan. Runs the checks that PHAN_ANALYZE_EXCLUDED_METHODS and PHAN_DISABLE_CLONE_REPLAY would restore, and the inherited @phan-mandatory-param and @throws lookups that are skipped when they cannot find anything, and exits with an error if any of them would have changed the result.
PHAN_VERIFY_SKIPPED_CHECKS=1 phanFor developing Phan. Writes the types and flags of every user-defined function and method to the given path when the analysis phase starts, to compare runs with and without the variables above.
PHAN_DUMP_METHOD_STATE_DIGEST=/tmp/digest.txt phan# Monitor peak memory
/usr/bin/time -v phan# Time the analysis
time phan#!/bin/bash
echo "Performance comparison"
echo "====================="
echo -e "\nStandard analysis:"
time phan
echo -e "\nIncremental analysis:"
time phan --incremental
echo -e "\nParallel (8 processes):"
time phan -j 8# Specify config file explicitly
phan --config-file .phan/config.php
# Or use no config
phan -n file.php# Output to file instead
phan -f output.txt
# Or use quiet mode
phan -q# Use incremental analysis
phan --incremental
# Use parallel processing
phan -j 8
# Reduce memory/accuracy tradeoff
phan --ast-trim-max-elements-per-level 128# Force full analysis
phan --force-full-analysis#!/bin/bash
set -e
echo "=== Phan Static Analysis ==="
# Install dependencies
composer install
# Create baseline on first run
if [ ! -f .phan/.baseline.php ]; then
echo "Creating baseline..."
phan --save-baseline .phan/.baseline.php
fi
# Run analysis
echo "Running analysis..."
phan \
--load-baseline .phan/.baseline.php \
--incremental \
--processes 8 \
--output-mode checkstyle \
--output-file reports/phan.xml
# Check results
if [ $? -eq 0 ]; then
echo "✓ Analysis passed"
else
echo "✗ Analysis found issues"
exit 1
fi- [[Phan-Config-Settings]] - Configuration file reference
- [[Migrating-to-Phan-V6]] - V6 breaking changes
- [[Incremental-Analysis]] - Detailed incremental analysis guide
- [[Memory-and-Performance-Optimizations]] - Performance tuning
- [[Using-Phan-Daemon-Mode]] - Daemon mode details