Use this skill for PHP language rules, coding style, Composer, namespacing, autoloading, object-oriented design, dependency injection, documentation, and performance.
Source reference:
https://phptherightway.com/
Write PHP that is:
PHP does not have only one canonical “right way,” so prefer widely accepted standards, documented project conventions, and clear tradeoffs over personal style.
Use the current stable PHP version supported by the project.
Default expectation:
PHP 8.2+
Do not introduce code that depends on unsupported PHP versions unless the project explicitly targets a legacy runtime.
When adding a language feature, verify that it is supported by the project’s configured PHP version in composer.json.
Example:
{
"require": {
"php": ">=8.2"
}
}
Follow recognized PHP standards unless the repository already defines stricter rules.
Preferred standards:
Use automated tooling rather than manual formatting arguments.
Recommended tools:
composer require --dev squizlabs/php_codesniffer
composer require --dev friendsofphp/php-cs-fixer
Example checks:
vendor/bin/phpcs --standard=PSR12 src tests
vendor/bin/php-cs-fixer fix --dry-run --diff
Example fix:
vendor/bin/php-cs-fixer fix
Use English names for code symbols and infrastructure.
Good:
class InvoiceRepository
{
public function findByCustomerId(int $customerId): array
{
// ...
}
}
Avoid unclear abbreviations:
class InvRepo
{
public function fbcid($cid)
{
// ...
}
}
<?php tags. Do not use short open tags.declare(strict_types=1);
public, protected, or private.All new application classes must use namespaces.
Use PSR-4 autoloading through Composer.
Example composer.json:
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
}
}
After changing autoload rules, run:
composer dump-autoload
Example class:
<?php
declare(strict_types=1);
namespace App\Service;
final class InvoiceCalculator
{
public function calculateTotal(array $items): int
{
return array_sum(array_column($items, 'amountCents'));
}
}
Use Composer for PHP dependencies.
Rules:
composer require or composer require --dev.composer.json and composer.lock for applications.vendor/.Commands:
composer install
composer update vendor/package
composer audit
composer validate
Use composer update intentionally. Do not casually update every dependency in unrelated work.
Prefer clear object-oriented code for domain and application logic.
Example:
final class CustomerName
{
public function __construct(private string $value)
{
if (trim($value) === '') {
throw new InvalidArgumentException('Customer name is required.');
}
}
public function value(): string
{
return $this->value;
}
}
Guidelines:
Prefer dependency injection over creating dependencies inside classes.
Good:
final class RegisterUser
{
public function __construct(
private UserRepository $users,
private PasswordHasher $passwords
) {
}
public function handle(string $email, string $plainPassword): void
{
$hash = $this->passwords->hash($plainPassword);
$this->users->create($email, $hash);
}
}
Avoid:
final class RegisterUser
{
public function handle(string $email, string $plainPassword): void
{
$users = new UserRepository();
$passwords = new PasswordHasher();
}
}
Rules:
Use PHPDoc where it adds clarity, especially for arrays, complex return values, and public APIs.
Good:
/**
* @return list<Customer>
*/
public function findActiveCustomers(): array
{
// ...
}
Avoid noisy comments that repeat the code:
// Increment i by one.
$i++;
Rules:
Rules:
Powered by TurnKey Linux.