php
PHP language conventions, modern idioms, and type system. Invoke whenever task involves any interaction with PHP code — writing, reviewing, refactoring, debugging, or understanding PHP projects.
What this skill does
# PHP
**Strict types, explicit contracts, no magic. If a class needs a docblock to explain what its properties do, the
properties are named wrong.**
PHP 8.5+ is the baseline. Use modern syntax unconditionally — union types, enums, readonly classes, property hooks,
named arguments, `match`, pipe operator. No backward compatibility with older PHP versions unless the project explicitly
requires it.
Every PHP file starts with `declare(strict_types=1)`.
## References
- **Type system** → `${CLAUDE_SKILL_DIR}/references/typing.md` — Union/intersection/DNF types, nullable patterns, typed
properties and constants, coercion rules, variance
- **OOP patterns** → `${CLAUDE_SKILL_DIR}/references/oop.md` — Interfaces, traits, readonly, property hooks, enums,
constructor promotion, lazy objects, magic methods
- **Concurrency** → `${CLAUDE_SKILL_DIR}/references/concurrency.md` — Fiber API, generator coroutines, comparison table,
async library guidance
- **Packaging** → `${CLAUDE_SKILL_DIR}/references/packaging.md` — composer.json templates, version constraints, project
layouts, namespace conventions
## Naming
- **Classes, interfaces, traits, enums** — PascalCase: `UserService`, `Renderable`, `Status`
- **Methods, functions** — camelCase: `findById`, `getFullName`
- **Properties, variables** — camelCase: `$userName`, `$isActive`
- **Constants (class and global)** — UPPER_SNAKE_CASE: `MAX_RETRIES`, `DEFAULT_LOCALE`
- **Namespaces** — PascalCase segments: `App\Http\Controller`
- **Enum cases** — PascalCase: `Status::Active`, `Suit::Hearts`
- **Descriptive names.** `$userCount` not `$n`. Short names (`$i`, `$k`, `$v`) only in tiny scopes (loops, array
operations).
- **No redundant context.** `$car->make` not `$car->carMake`.
- **Boolean names:** `is`/`has`/`can`/`should` prefix: `$isValid`, `$hasAccess`.
- **Abbreviations as words.** `HttpClient` not `HTTPClient`, `JsonParser` not `JSONParser`. Treat abbreviations and
acronyms as regular words — uppercase first letter only (PER-CS).
- **No underscore prefix** for protected/private visibility. Visibility modifiers exist for that.
## Type Declarations
PHP 8.5+ provides a complete type system. Use it everywhere.
### Core Rules
- **Type all public API boundaries** — function parameters, return types, class properties, class constants.
Internal/private code benefits from types too.
- **`declare(strict_types=1)`** in every file. No exceptions.
- **Short type names:** `bool`, `int`, `float`, `string`. Never `boolean`, `integer`, `double`.
- **Union types with `|`:** `string|int`, `Foo|null`. Prefer `?T` for single-type nullable.
- **Intersection types with `&`:** `Countable&Traversable`. Class/interface types only.
- **DNF types:** `array|(ArrayAccess&Traversable)` — union of intersections in parentheses.
- **`void` return:** annotate on functions that return nothing.
- **`never` return:** functions that always throw or exit.
- **Avoid `mixed`** — it disables type safety. Use `object` when you mean "any object." Use `mixed` only at true interop
boundaries with untyped code.
- **`null` last in unions:** `string|int|null`, not `null|string|int`.
### Typed Properties
- Every class property gets a type declaration.
- Typed properties must be initialized before access — use constructor promotion, default values, or constructor
assignment.
- `callable` cannot be used as a property type. Use `Closure` instead.
### Typed Constants (8.3+)
```php
class Config
{
public const int MAX_RETRIES = 3;
public const string DEFAULT_LOCALE = 'en';
protected const float TAX_RATE = 0.21;
}
```
- Type all class constants. Interface constants especially — they enforce the contract at compile time.
### Variance
- **Parameters are contravariant** — child class can accept wider types.
- **Return types are covariant** — child class can return narrower types.
- `mixed` return can be narrowed to any type in a subclass.
See `${CLAUDE_SKILL_DIR}/references/typing.md` for the complete type system reference.
## Enumerations
- **Use enums for categorical constants.** Never bare strings or ints as pseudo-enums.
- **Backed enums** (`string` or `int`) when the value must interoperate with external systems (JSON, database, API).
- **`from()` throws on invalid value; `tryFrom()` returns `null`.** Choose based on whether invalid input is a caller
error or expected.
- **Enums can implement interfaces** and define methods. Use this for behavior tied to the enum's domain.
- **Enums cannot have state** (no properties), cannot be extended, cannot be `new`'d.
- **Dynamic access:** `Status::{$name}` (8.3+) for variable-based case resolution.
```php
enum Status: string
{
case Active = 'active';
case Inactive = 'inactive';
case Suspended = 'suspended';
public function label(): string
{
return match ($this) {
self::Active => 'Active',
self::Inactive => 'Inactive',
self::Suspended => 'Suspended',
};
}
}
```
## Classes
### Properties and Visibility
- **Explicit visibility on everything** — properties, methods, constants.
- **Constructor promotion** for data-carrying classes:
```php
class User
{
public function __construct(
public readonly string $name,
private string $email,
protected int $age = 0,
) {}
}
```
- **Readonly properties** (8.1+) for immutable state. Must have a type declaration.
- **Readonly classes** (8.2+) — all properties implicitly readonly, no dynamic properties.
- **Asymmetric visibility** (8.4+) — `public protected(set)` for publicly readable, internally writable properties.
- **Property hooks** (8.4+) — `get`/`set` logic on properties. Use instead of trivial getter/setter methods.
Incompatible with `readonly`.
### Inheritance and Composition
- **Composition over inheritance.** Use inheritance only for true "is-a" relationships.
- **Interfaces for contracts.** All interface methods are public. As of 8.4, interfaces can declare property
requirements.
- **Abstract classes** when you need shared implementation alongside a contract.
- **Traits for horizontal reuse.** Never use traits as a substitute for interfaces. One `use` statement per trait, each
on its own line.
- **`#[Override]`** (8.3+) on every method that overrides a parent or implements an interface method. Catches signature
drift at compile time.
- **`super()` equivalent:** always use `parent::method()`. Never hardcode grandparent class names.
### Magic Methods
- **Avoid property overloading** (`__get`, `__set`) in new code. Typed properties with hooks are strictly better.
- **`__toString()`** — define when string conversion has meaningful semantics.
- **`__invoke()`** — for single-method objects that act as callables.
- **`__serialize()` / `__unserialize()`** — prefer over `__sleep()` / `__wakeup()`.
### Object Patterns
- **Value objects** — `readonly class` with constructor promotion. Immutable by default.
- **DTOs** — readonly classes with public properties. No behavior.
- **Service classes** — constructor injection for dependencies, no public state.
- **Lazy objects** (8.4+) — defer initialization via `ReflectionClass::newLazyGhost()`.
## Functions
- **Early return.** Guard clauses first, happy path flat. Reduce nesting.
- **One function, one job.** If the name contains "and", split it.
- **Type all parameters and return types** on public functions.
- **Named arguments** for functions with boolean flags or many optional parameters:
`createUser(name: 'John', admin: true)`.
- **`match` over `switch`** — `match` is an expression, uses strict comparison, and does not fall through.
- **Pipe operator** (8.5+) for functional chaining:
```php
$result = $input
|> trim(...)
|> strtolower(...)
|> ucfirst(...);
```
- **First-class callables** with `...` syntax: `array_map(strlen(...), $strings)`.
- **Arrow functions** for short closures: `fn($x) => $x * 2`. Arrow functions capture by Related in Productivity
gitea-workflow
IncludedOrchestrate agile development workflows for Gitea repositories using the tea CLI. Use when working with Gitea-hosted repos and asking to 'run the workflow', 'continue working', 'what's next', 'complete the task cycle', 'start my day', 'end the sprint', 'implement the next task', or wanting guided step-by-step development assistance. Keywords: workflow, orchestrate, agile, task cycle, sprint, daily, implement, review, PR, standup, retrospective, gitea, tea.
microsoft-graph-gateway
IncludedRoute Microsoft Graph work in this workspace. Use when users want to read or write Outlook mail, calendar events, contacts, OneDrive or SharePoint files, Teams, Planner, To Do, users, groups, directory data, or arbitrary Microsoft Graph endpoints from VS Code. Prefer WorkIQ for common read scenarios. Use Microsoft Graph for write actions and gap-read scenarios that need exact Graph properties, filters, permissions, or endpoints.
copilotkit
IncludedUse when building with CopilotKit — setup, development, integrations, debugging, upgrading, or contributing. Routes to the appropriate specialized skill based on the task.
wordly-wisdom
IncludedProvides calibrated decision analysis using Charlie Munger-style multiple mental models, inversion, incentive mapping, circle-of-competence checks, misjudgment audits, second-order effects, and forecast updates. Use when the user asks for an oracle take, a hard call, a decision memo, a premortem, an outside view, a red-team, a sanity-check, what am I missing, think this through, or wants a strategy, hire, investment, plan, product, partnership, or major life choice analysed. Avoid for simple factual lookups or time-sensitive legal, medical, or market questions without fresh evidence.
swain-session
IncludedSession management and project status dashboard. Owns the full session lifecycle (start/work/close/resume), focus lane, bookmarks, worktree detection, and tab naming. Also serves as the project status dashboard — shows active epics, progress, actionable next steps, blocked items, tasks, GitHub issues, and recommendations. Worktree creation is deferred to swain-do task dispatch (SPEC-195). Triggers on: 'session', 'status', 'what's next', 'dashboard', 'overview', 'where are we', 'what should I work on', 'show me priorities', 'bookmark', 'focus on', 'session info'.
gandi
IncludedComprehensive Gandi domain registrar integration for domain and DNS management. Register and manage domains, create/update/delete DNS records (A, AAAA, CNAME, MX, TXT, SRV, and more), configure email forwarding and aliases, check SSL certificate status, create DNS snapshots for safe rollback, bulk update zone files, and monitor domain expiration. Supports multi-domain management, zone file import/export, and automated DNS backups. Includes both read-only and destructive operations with safety controls.