php-the-right-way
Purpose
Guide PHP code to follow modern, idiomatic best practices as defined by the PHP community. Apply these rules when writing, reviewing, or refactoring any PHP code.
Core Rules (always apply)
Version
- Use PHP 8.2+ features; never write PHP 7.x style code for new projects
- Enable strict types:
declare(strict_types=1);at the top of every file
Code Style
- Follow PSR-12 for formatting + PSR-4 for autoloading
- Use Composer for all dependency management — never manual
require - Run
php-cs-fixerorphpcsto enforce style automatically
Comparisons
- Always use strict comparison (
===,!==) — never loose== - Check
strpos(),array_search()etc. with!== false, not truthiness
OOP
- Declare return types, parameter types, and property types on all methods
- Use
readonlyproperties (PHP 8.1+) for immutable data / DTOs - Prefer
enum(PHP 8.1+) over class constants for fixed value sets - Use constructor property promotion to reduce boilerplate
- Use interfaces to define contracts; depend on abstractions, not concretions
- Use named arguments for clarity on functions with many params
Namespaces
- Every class must live in a namespace following PSR-4
- Never pollute the global namespace
- Prefix internal function calls with
\when inside a namespace (e.g.,\array_map())
Error Handling
- Use typed exceptions — never
throw new \Exception('generic message') - Catch specific exceptions, not bare
\Exception - Never suppress errors with
@ - Set
error_reporting(E_ALL)in development; log errors in production
Security (non-negotiable)
- SQL: Always use PDO/MySQLi with prepared statements — never string interpolation in queries
- Output: Always
htmlspecialchars($var, ENT_QUOTES, 'UTF-8')before echoing user input - Passwords: Use
password_hash()/password_verify()— never MD5/SHA1 - CSRF: Include CSRF tokens on all state-changing forms
- Input: Filter input with
filter_var()/filter_input() - Sessions: Regenerate session ID on login:
session_regenerate_id(true)
References
Load these when needed:
- basics.md — Strings, comparisons, ternary, control flow gotchas
- design-patterns.md — Factory, Singleton, Strategy, MVC, Front Controller
- security.md — XSS, SQL injection, CSRF, password hashing, sessions
- tooling.md — Composer, PHPUnit/Pest, Xdebug, php-cs-fixer, PHPStan
Workflow: Code Review
- Check strict types declaration at top
- Verify all comparisons are strict (
===) - Check for raw SQL strings (injection risk)
- Check output escaping (XSS risk)
- Verify password handling (never MD5/SHA1)
- Check PSR-4 namespacing and PSR-12 style
- Look for missing type declarations
- Flag any
@error suppression
Workflow: Code Generation
- Start with
declare(strict_types=1); - Apply PSR-4 namespace matching directory structure
- Type all parameters, return values, and properties
- Use constructor property promotion for simple classes
- Throw typed exceptions with descriptive messages
- Add PHPDoc only when types alone aren't self-documenting
More from masterfermin02/agent-skills
laravel-money
Use the cknow/laravel-money package for Laravel projects that need to model, persist, cast, format, compare, or calculate money safely. Trigger when working on Laravel apps that handle currency, prices, totals, invoices, billing, checkout, discounts, taxes, balances, monetary casts, or any request mentioning money handling, currency formatting, integer minor units, Money value objects, or 'laravel-money'. Prefer this over raw floats for monetary values in Laravel.
2unit-testing
Write, review, and improve unit tests using best practices. Framework-agnostic — applies to any language or test framework (xUnit, Jest, PHPUnit, Pest, JUnit, etc.). Use when writing new unit tests, reviewing existing tests for quality, refactoring fragile or brittle tests, choosing between mocks/stubs/fakes/spies, naming tests, structuring test files, identifying anti-patterns, generating test doubles, or applying patterns like AAA, Object Mother, Builder, or Assert Object. Also triggers on phrases like generate tests for this code, my tests are brittle, tests keep breaking, how do I mock this, what is the difference between mock and stub, write a test for, add tests to, test coverage, unit test this, improve my tests, tests are hard to maintain.
1pr-review
Code review GitHub Pull Requests. Use whenever asked to review a PR, check a pull request, audit a diff, or give feedback on a GitHub PR. Triggers on: 'review this PR', 'code review', 'check this PR', 'review pull request', GitHub PR URLs (github.com/.../pull/NNN), or any request to audit code changes. Supports private repos via GitHub token. Delegates to language-specific skills (laravel-best-practices, csharp-best-practices, php-the-right-way) when applicable.
1php-update-with-rector
>
1ai-era-architecture
Define pragmatic software architecture for the AI era using rules like making important logic easy to find, keeping changes local, reducing coupling where it matters, protecting critical business rules, making debugging less painful, supporting safe iteration, and avoiding unnecessary ceremony. Use when designing project structure, evaluating whether clean architecture is worth it, or setting architecture principles for modern teams.
1frontend-pragmatic-architecture
Apply pragmatic AI-era architecture rules to frontend projects such as React, Next.js, or similar frameworks. Use when organizing pages, features, components, hooks, UI state, and frontend API calls so important logic stays easy to find and changes stay local.
1