PHP CodeSniffer Basics
What is PHP CodeSniffer?
PHP CodeSniffer (PHPCS) detects violations of coding standards. It's a static analysis tool focused on code style.
Installation
composer require --dev squizlabs/php_codesniffer
composer require --dev magento/magento-coding-standard
Basic Usage
# Check a file
vendor/bin/phpcs app/code/Vendor/Module/Model/Product.php
# Check a directory
vendor/bin/phpcs app/code/Vendor/Module/
# Use Magento standard
vendor/bin/phpcs --standard=Magento2 app/code/Vendor/Module/
# Auto-fix issues
vendor/bin/phpcbf --standard=Magento2 app/code/Vendor/Module/
# Show report in different format
vendor/bin/phpcs --report=csv app/code/Vendor/Module/
php.xml Configuration
<!-- phpcs.xml -->
<ruleset name="Magento2 Custom">
<description>Custom Magento 2 coding standard</description>
<arg name="extensions" value="php"/>
<arg value="sp"/> <!-- Show progress -->
<!-- Use Magento2 standard as base -->
<rule ref="Magento2"/>
<!-- Paths to check -->
<file>app/code/Vendor/Module</file>
<!-- Exclude files -->
<exclude-pattern>*/Test/*</exclude-pattern>
<exclude-pattern>*/generated/*</exclude-pattern>
<exclude-pattern>*/_files/*</exclude-pattern>
<!-- Config -->
<config name="minimum_supported_php_version" value="8.1"/>
<config name="testVersion" value="8.1-"/>
</ruleset>
Running
# Use phpcs.xml config automatically
vendor/bin/phpcs
# Or specify config
vendor/bin/phpcs --standard=phpcs.xml
Magento 2 Coding Standard
Key Magento 2 Coding Rules
Naming Conventions
// Classes: PascalCase
namespace Vendor\Module\Model;
class ProductExporter { /* ... */ } // Correct
class product_exporter { /* ... */ } // Wrong
// Methods: camelCase
public function getProductPrice(): float { /* ... */ } // Correct
public function get_product_price(): float { /* ... */ } // Wrong
// Variables: camelCase
$productName = 'Test'; // Correct
$product_name = 'Test'; // Wrong (unless snake_case for DB columns)
// Constants: UPPER_SNAKE_CASE
public const STATUS_ACTIVE = 1; // Correct
public const statusActive = 1; // Wrong
Indentation and Spacing
// 4 spaces indentation (no tabs)
class Product
{
public function getName(): string // Space after method name
{
return $this->name; // 4 spaces, not tabs
}
}
// Space after comma in arrays
$array = ['key1' => 'value1', 'key2' => 'value2'];
// No space before semicolon
$value = 'test'; // Correct
$value = 'test' ; // Wrong
PHPDoc Requirements
/**
* Product export service.
*
* @api
*/
class ProductExporter
{
/**
* Export product data to CSV format.
*
* @param ProductInterface $product
* @return string CSV formatted data
* @throws \InvalidArgumentException if product is null
*/
public function export(ProductInterface $product): string
{
// ...
}
}
Magento-Specific Rules
// Use __() for translatable strings
throw new \Magento\Framework\Exception\LocalizedException(
__('Product not found')
); // Correct
throw new \Magento\Framework\Exception\LocalizedException(
new \Magento\Framework\Phrase('Product not found')
); // Also correct, but __() is preferred
// Use interfaces for type hints
public function save(\Magento\Catalog\Api\Data\ProductInterface $product) // Correct
public function save(\Magento\Catalog\Model\Product $product) // Wrong
Custom Sniffs and PHP-CS-Fixer
Custom Sniff Rule
namespace Vendor\Module\PHP_CodeSniffer\Sniffs\Commenting;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
class ForbiddenTODOCommentSniff implements Sniff
{
public function register(): array
{
return [T_COMMENT];
}
public function process(File $phpcsFile, $stackPtr): void
{
$comment = $phpcsFile->getTokens()[$stackPtr];
if (str_contains($comment['content'], 'TODO') ||
str_contains($comment['content'], 'FIXME')) {
$phpcsFile->addWarning(
'TODO/FIXME comments are not allowed in production code',
$stackPtr,
'ForbiddenTodo'
);
}
}
}
Register in ruleset:
<ruleset name="Magento2 Custom">
<rule ref="Magento2"/>
<rule name="Vendor\Module\PHP_CodeSniffer\Sniffs\Commenting\ForbiddenTODOCommentSniff"/>
</ruleset>
PHP-CS-Fixer (Alternative)
# Install
composer require --dev friendsofphp/php-cs-fixer
# Run
vendor/bin/php-cs-fixer fix app/code/Vendor/Module/
# Dry run (show changes without applying)
vendor/bin/php-cs-fixer fix --dry-run --diff app/code/Vendor/Module/
// .php-cs-fixer.dist.php
return (new PhpCsFixer\Config())
->setRules([
'@PER-CS2.0' => true,
'array_syntax' => ['syntax' => 'short'],
'no_unused_imports' => true,
'ordered_imports' => ['sort_algorithm' => 'alpha'],
'single_quote' => true,
'trailing_comma_in_multiline' => true,
])
->setFinder(
PhpCsFixer\Finder::create()
->in(__DIR__ . '/app/code/Vendor/Module')
);
CI Integration
# .github/workflows/coding-standard.yml
name: Coding Standard
on: [push, pull_request]
jobs:
phpcs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
- run: composer install
- run: vendor/bin/phpcs --standard=phpcs.xml --report=checkstyle > phpcs.xml
php-cs-fixer:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
- run: composer install
- run: vendor/bin/php-cs-fixer fix --dry-run --diff
Quiz
1. What is the Magento 2 coding standard for class names?
2. How do you auto-fix PHPCS violations?
3. PHPCS is primarily for detecting:
Flashcards
Question
What does PHPCS detect?
Click to reveal answer
Answer
Coding standard violations (style, naming, formatting)
Question
Magento 2 class naming convention?
Click to reveal answer
Answer
PascalCase (ProductExporter, OrderRepository)
Question
How to auto-fix PHPCS violations?
Click to reveal answer
Answer
vendor/bin/phpcbf --standard=Magento2
Question
Magento coding standard package?
Click to reveal answer
Answer
magento/magento-coding-standard
Revision Notes
Key Takeaways
- 1. PHPCS detects coding standard violations (style, naming, formatting)
- 2. Magento 2 standard: PascalCase classes, camelCase methods, 4-space indentation
- 3. phpcbf auto-fixes violations; phpstan finds type errors
- 4. PHP-CS-Fixer is an alternative with more configurable rules
- 5. Integrate both into CI pipeline for consistent code style
Interview Tips
- • Know Magento naming conventions: PascalCase classes, camelCase methods
- • Explain the difference between PHPCS (style) and PHPStan (types)
- • Discuss how to adopt coding standards gradually in existing codebases
Cheat Sheet
PHPCS: vendor/bin/phpcs --standard=Magento2 src/
PHPCBF: vendor/bin/phpcbf --standard=Magento2 src/
Magento2 Standard:
Classes: PascalCase
Methods: camelCase
Constants: UPPER_SNAKE_CASE
Indentation: 4 spaces (no tabs)
Strings: Use __() for translatable strings
Config: phpcs.xml
<rule ref="Magento2"/>
<file>app/code/Vendor/Module</file>
<exclude-pattern>*/Test/*</exclude-pattern>