CLI Toolchain: Composer, Laravel Pint, PHPStan, Rector
A productive PHP 8 workflow on macOS relies on a small set of CLI tools. This page covers the essential ones — how to install, configure, and integrate them into your daily development process.
Composer — Dependency Manager
Composer is the cornerstone of modern PHP development. Install it globally:
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
chmod +x /usr/local/bin/composer
composer --version
# Composer version 2.x.x
Essential Composer Commands
# Initialize a new project
composer init
# Install dependencies from composer.lock
composer install
# Add a new dependency
composer require league/oauth2-client
# Add a dev dependency
composer require --dev pestphp/pest
# Update all packages to latest compatible versions
composer update
# Dump optimized autoload (for production)
composer dump-autoload --optimize --classmap-authoritative
# Check for security vulnerabilities
composer audit
composer.json Best Practices
{
"name": "myapp/api",
"require": {
"php": "^8.3",
"ext-json": "*",
"ext-pdo": "*"
},
"require-dev": {
"pestphp/pest": "^3.0",
"phpstan/phpstan": "^1.0",
"laravel/pint": "^1.0"
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"config": {
"optimize-autoloader": true,
"sort-packages": true,
"allow-plugins": {
"pestphp/pest-plugin": true
}
}
}
Laravel Pint — Code Style Fixer
Laravel Pint is an opinionated PHP code style fixer built on PHP-CS-Fixer. It enforces PSR-12 with sensible defaults.
composer require --dev laravel/pint
Basic Usage
# Check for style violations (dry-run)
./vendor/bin/pint --test
# Fix all violations
./vendor/bin/pint
# Fix a specific file or directory
./vendor/bin/pint src/Models/User.php
./vendor/bin/pint src/
pint.json Configuration
Create pint.json in your project root to customize rules:
{
"preset": "psr12",
"rules": {
"array_syntax": { "syntax": "short" },
"ordered_imports": { "sort_algorithm": "alpha" },
"no_unused_imports": true,
"not_operator_with_successor_space": true,
"trailing_comma_in_multiline": {
"elements": ["arrays", "arguments", "parameters"]
}
}
}
Available presets: laravel, psr12, symfony, per
Run on Save (VS Code)
Install the Laravel Pint extension and add to .vscode/settings.json:
{
"editor.formatOnSave": true,
"[php]": {
"editor.defaultFormatter": "open-southeners.laravel-pint"
}
}
PHPStan — Static Analysis
PHPStan analyzes your code without running it, catching type errors, undefined variables, and logic bugs at development time.
composer require --dev phpstan/phpstan
Running PHPStan
# Analyze src/ at level 5
./vendor/bin/phpstan analyse src --level=5
# Analyze with config file
./vendor/bin/phpstan analyse
phpstan.neon Configuration
parameters:
level: 8
paths:
- src
- tests
excludePaths:
- src/Legacy
checkMissingIterableValueType: false
treatPhpDocTypesAsCertain: false
PHPStan Levels
| Level | What It Checks |
|---|---|
| 0 | Basic checks (undefined variables, classes) |
| 1 | Possibly undefined variables |
| 2 | Unknown methods on $this |
| 3 | Return types |
| 4 | Dead code, always true conditions |
| 5 | Method arguments type checking |
| 6 | Check type of passed arguments |
| 7 | Report mixed usage |
| 8 | Report callable signatures |
| 9 | Be pedantic — the strictest level |
Best practice: Start at level 5 for existing projects, level 8 for new projects. Use a baseline to suppress pre-existing errors.
Generating a Baseline
When adding PHPStan to a large existing codebase:
./vendor/bin/phpstan analyse --generate-baseline
# Creates phpstan-baseline.neon
Include the baseline in your config:
includes:
- phpstan-baseline.neon
Now CI enforces no new errors while letting you fix baseline violations gradually.
Rector — Automated Refactoring
Rector automatically upgrades your PHP code and applies best practices.
composer require --dev rector/rector
rector.php Configuration
<?php
use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList;
use Rector\Set\ValueObject\SetList;
return RectorConfig::configure()
->withPaths([
__DIR__ . '/src',
__DIR__ . '/tests',
])
->withSets([
LevelSetList::UP_TO_PHP_83, // Upgrade to PHP 8.3 syntax
SetList::CODE_QUALITY, // General code quality
SetList::DEAD_CODE, // Remove dead code
SetList::TYPE_DECLARATION, // Add type declarations
]);
Running Rector
# Preview changes (dry run)
./vendor/bin/rector --dry-run
# Apply changes
./vendor/bin/rector
Makefile — Tying It All Together
Create a Makefile to standardize your workflow:
.PHONY: lint analyse test fix
lint:
./vendor/bin/pint --test
fix:
./vendor/bin/pint
analyse:
./vendor/bin/phpstan analyse
test:
./vendor/bin/pest --coverage
ci: lint analyse test
Now your CI/CD and local workflow share a single entry point:
make ci # Runs lint + analyse + test
make fix # Auto-fix code style
Summary: Your PHP 8 Toolchain
macOS
└── Homebrew
└── PHP 8.3 (shivammathur/php)
└── Composer
├── laravel/pint → Code style (PSR-12)
├── phpstan/phpstan → Static analysis (types, logic)
├── rector/rector → Auto-refactoring
└── pestphp/pest → Testing (next chapter)
With this toolchain in place, your IDE catches problems instantly, Pint keeps code formatted, PHPStan enforces type correctness, and Rector keeps your code modern — all before a single test runs.