--- name: php description: Builds PHP code, database migrations, and PHPUnit tests category: development --- # PHP Developer Builds PHP code, database migrations, and tests for a feature. ## When to Use ``` /php features/PROJ-X-feature-name.md ``` ## Skill Steps 1. **Read context** - Read `features/INDEX.md` for feature overview - Read the feature spec for requirements and tech design - Check existing structure: `ls src/`, `ls tests/` 2. **Implement PHP code** - Create/update classes in `src/` directory - Follow PSR-12 coding standard - Use typed properties and return types - Add `declare(strict_types=1);` to all PHP files 3. **Implement migrations** - Add migration file in `migrations/` directory - Use portable SQL (see `docs/production/database-portability.md`) - Use `IF NOT EXISTS` for idempotency 4. **Write tests** - PHPUnit tests in `tests/` directory - Test one thing per method - Test both happy path and error paths 5. **Run checks** - `composer lint` (fix any style issues) - `composer analyze` (fix any static analysis errors) - `composer test` (all tests must pass) 6. **Update tracking** - Mark feature as "Implemented" in `features/INDEX.md` 7. **Suggest next step** - Recommend `/qa` next ## Tech Design Section Format (for feature specs) ```markdown ## Tech Design ### Classes - `UserRepository`: handles user CRUD operations - `UserService`: business logic for users ### Database Schema ```sql CREATE TABLE users ( id INTEGER PRIMARY KEY, email TEXT NOT NULL UNIQUE, name TEXT NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); ``` ### Implementation Order 1. Create migration 2. Implement UserRepository 3. Implement UserService 4. Write tests ``` ## Rules - **PSR-12**: All code follows PSR-12 coding standard - **Strict types**: All files start with `declare(strict_types=1);` - **Parameterized queries**: Never interpolate user input into SQL - **Portable SQL**: Works on SQLite, MariaDB, and PostgreSQL - **Tests**: Write tests for all new classes/methods ## Context Recovery If context is compacted: 1. Re-read feature spec 2. Check `git status` for uncommitted changes 3. Continue from next class/method to implement