Skip to main content
php-guide PHP language guardrails, patterns, and best practices for AI-assisted development.
Use when working with PHP files (.php), composer.json, or when the user mentions PHP.
Provides type declaration patterns, Composer conventions, PSR standards,
and testing guidelines specific to this project's coding standards.
インストールへ移動 Skills Marketplace コミュニティが作成したAIスキルを発見・探索
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
直接コマンドでは確認用 Prompt が省略されます。実行前にソースを確認してください。
npx skills add https://github.com/ar4mirez/samuel --skill php-guideコマンドは1行のまま表示されます。コピー前に横へスクロールして全体を確認してください。
ローカルで確認しますか?SkillsMP が現在取得できるファイルをダウンロードできます。
Zipをダウンロード ダウンロード中... name php-guide description PHP language guardrails, patterns, and best practices for AI-assisted development.
Use when working with PHP files (.php), composer.json, or when the user mentions PHP.
Provides type declaration patterns, Composer conventions, PSR standards,
and testing guidelines specific to this project's coding standards.
license MIT metadata {"author":"samuel","version":"1.0","category":"language","language":"php","extensions":".php"}
PHP Guide
Applies to: PHP 8.1+, Web Applications, APIs, CLIs, Microservices
Core Principles
Strict Types Always : Every PHP file starts with declare(strict_types=1)
Type Declarations Everywhere : All parameters, return types, and properties must have type declarations
PSR Standards : Follow PSR-12 coding standard, PSR-4 autoloading, PSR-7 HTTP messages
Composition Over Inheritance : Prefer interfaces, traits, and dependency injection over deep class hierarchies
Modern PHP First : Use PHP 8.1+ features (enums, readonly properties, fibers, named arguments, match expressions)
Guardrails
Version & Dependencies
Target PHP 8.1+ (enums, readonly properties, fibers, intersection types)
Define all dependencies in composer.json with version constraints
Run composer validate and composer audit before committing
Use composer.lock for applications (commit it), omit for libraries
Separate require-dev for development-only dependencies
Never use composer update in production (use composer install --no-dev)
Code Style (PSR-12)
Run PHP-CS-Fixer or PHP_CodeSniffer before every commit
Naming: PascalCase classes/enums, camelCase methods/properties, UPPER_SNAKE constants
One class per file, file name matches class name
Opening braces on same line for control structures, next line for classes/methods
declare(strict_types=1) as first statement after <?php in every file
No closing ?> tag in pure PHP files
Imports: one use per declaration, grouped (classes, functions, constants), alphabetized
<?php
declare (strict_types=1 );
namespace App \Domain \User ;
use App \Domain \Exception \ValidationException ;
use App \Domain \ValueObject \Email ;
final class UserService
{
public function __construct (
private readonly UserRepositoryInterface $repository ,
private readonly EventDispatcherInterface $dispatcher ,
) {}
public function register (string $name , string $email ): User
{
$emailVO = Email ::fromString ($email );
if ($this ->repository->existsByEmail ($emailVO )) {
throw ValidationException ::duplicateEmail ($email );
}
$user = User ::create (name : $name , email : $emailVO );
$this ->repository->save ($user );
$this ->dispatcher->dispatch (new UserRegistered ($user ->id));
return $user ;
}
}
Type Declarations
All function parameters MUST have type declarations
All methods MUST declare return types (including void)
Use union types (string|int) instead of mixed when possible
Use intersection types (Countable&Iterator) for combined type constraints
Use Type|null for nullable parameters (prefer explicit over ?Type)
Use never return type for functions that always throw or exit
Avoid mixed -- if truly needed, document why
Error Handling
Never use @ error suppression operator
Convert PHP errors to exceptions with set_error_handler at bootstrap
Create domain-specific exception hierarchies extending a base exception
Use specific exception types (not generic \Exception or \RuntimeException)
Always include context in exception messages
Catch specific exceptions, never bare catch (\Throwable $e) without re-throwing
Use previous parameter to chain exceptions
<?php
declare (strict_types=1 );
namespace App \Domain \Exception ;
abstract class DomainException extends \RuntimeException
{
public function __construct (
string $message ,
public readonly string $errorCode = 'UNKNOWN' ,
int $code = 0 ,
?\Throwable $previous = null ,
) {
parent ::__construct ($message , $code , $previous );
}
}
final class NotFoundException extends DomainException
{
public static function forResource (string $resource , string $id ): self
{
return new self (
message: sprintf ('%s with ID "%s" not found' , $resource , $id ),
errorCode: 'NOT_FOUND' ,
);
}
}
Security
All user input validated before processing (filter functions or validation libraries)
All SQL queries use prepared statements with bound parameters (PDO or Doctrine DBAL)
All output escaped for context: htmlspecialchars() for HTML, parameterized for SQL
All file operations validate paths (realpath() + check against allowed directories)
Never use eval(), exec(), system(), passthru(), or backtick operator with user input
Use password_hash() with PASSWORD_ARGON2ID (or PASSWORD_BCRYPT minimum)
Set session.cookie_httponly, session.cookie_secure, session.cookie_samesite
Use CSRF tokens for all state-changing requests
Project Structure myproject/
├── src/ # Application source (PSR-4: App\)
│ ├── Domain/ # Business logic, entities, value objects
│ ├── Application/ # Use cases, command/query handlers
│ ├── Infrastructure/ # Framework, database, external services
│ └── Kernel.php
├── tests/
│ ├── Unit/ # Fast, isolated unit tests
│ ├── Integration/ # Tests with real dependencies
│ └── bootstrap.php
├── config/ # Configuration files
├── public/ # Web root (index.php entry point)
├── composer.json
├── composer.lock
├── phpunit.xml
├── phpstan.neon
└── .php-cs-fixer.php
PSR-4 autoloading: "App\\": "src/" in composer.json
Domain layer has zero framework dependencies
Infrastructure implements domain interfaces
One class per file, directory structure mirrors namespace
Keep public/ as the web root with a single index.php front controller
Key Patterns Use PHP 8.1+ features idiomatically:
Enums : Backed enums with methods for labels, state machines, role-based permissions
Readonly classes (PHP 8.2+): Value objects, DTOs, Money pattern -- all properties implicitly readonly
Named arguments : Improve readability for constructors and functions with many parameters
Match expressions : Prefer over switch -- strict comparison, expression-based, no fallthrough
Fibers : Cooperative multitasking foundation for async frameworks
Enums (PHP 8.1+) <?php
declare (strict_types=1 );
enum UserRole : string
{
case Admin = 'admin' ;
case Editor = 'editor' ;
case Viewer = 'viewer' ;
public function label ( ): string
{
return match ($this ) {
self ::Admin => 'Administrator' ,
self ::Editor => 'Editor' ,
self ::Viewer => 'Viewer' ,
};
}
public function permissions ( ): array
{
return match ($this ) {
self ::Admin => Permission ::cases (),
self ::Editor => [Permission ::Read , Permission ::Write ],
self ::Viewer => [Permission ::Read ],
};
}
}
Readonly Classes (PHP 8.2+) <?php
declare (strict_types=1 );
readonly class Money
{
public function __construct (
public int $amount ,
public string $currency ,
) {}
public function add (self $other ): self
{
if ($this ->currency !== $other ->currency) {
throw new \InvalidArgumentException ('Cannot add different currencies' );
}
return new self ($this ->amount + $other ->amount, $this ->currency);
}
}
See references/patterns.md for additional patterns: dependency injection, repository pattern, value objects, command/handler, fibers, match expressions, and tooling configurations.
Testing
Standards
Test files: *Test.php in tests/ mirroring src/ structure
Test methods: test_<unit>_<scenario>_<expected> or #[Test] attribute
PHPUnit as primary framework; Pest as alternative
Coverage: >80% business logic, >60% overall
Use data providers for parameterized tests
Mock external dependencies with Mockery or PHPUnit mocks
No database or network calls in unit tests
Each test method tests one behavior
PHPUnit with Data Providers <?php
declare (strict_types=1 );
namespace Tests \Unit \Domain \ValueObject ;
use App \Domain \Exception \ValidationException ;
use App \Domain \ValueObject \Email ;
use PHPUnit \Framework \Attributes \DataProvider ;
use PHPUnit \Framework \Attributes \Test ;
use PHPUnit \Framework \TestCase ;
final class EmailTest extends TestCase
{
#[Test ]
#[DataProvider ('validEmailProvider' )]
public function it_accepts_valid_emails (string $input ): void
{
$email = Email ::fromString ($input );
self ::assertSame (strtolower ($input ), $email ->toString ());
}
public static function validEmailProvider ( ): iterable
{
yield 'simple' => ['user@example.com' ];
yield 'with subdomain' => ['user@mail.example.com' ];
yield 'with plus' => ['user+tag@example.com' ];
yield 'uppercase' => ['User@Example.COM' ];
}
#[Test ]
#[DataProvider ('invalidEmailProvider' )]
public function it_rejects_invalid_emails (string $input ): void
{
$this ->expectException (ValidationException ::class );
Email ::fromString ($input );
}
public static function invalidEmailProvider ( ): iterable
{
yield 'empty string' => ['' ];
yield 'no at sign' => ['userexample.com' ];
yield 'no domain' => ['user@' ];
yield 'no local part' => ['@example.com' ];
yield 'spaces' => ['user @example.com' ];
}
}
Tooling
Required Dev Dependencies
phpunit/phpunit ^10.0 -- testing
phpstan/phpstan ^1.10 -- static analysis (level 8)
friendsofphp/php-cs-fixer ^3.0 -- code style
mockery/mockery ^1.6 -- mocking
vimeo/psalm ^5.0 -- alternative static analysis
PHPStan: Always Level 8 # phpstan.neon
parameters:
level: 8
paths:
- src
treatPhpDocTypesAsCertain: false
checkMissingIterableValueType: true
Essential Commands composer install
composer validate
composer audit
php vendor/bin/phpunit
php vendor/bin/phpunit --coverage-text
php vendor/bin/phpstan analyse
php vendor/bin/psalm
php vendor/bin/php-cs-fixer fix
php vendor/bin/php-cs-fixer fix --dry-run --diff
References For detailed code examples, see:
references/patterns.md -- Enum patterns, readonly classes, dependency injection, repository pattern, type declarations, error handling, modern PHP features, mocking, tooling configurations
External References