# AGENTS.md - Hyperf Skeleton Development Guide This document provides guidelines for agentic coding agents working in this Hyperf framework project. ## Project Overview - **Framework**: Hyperf ~3.1.0 (PHP coroutine framework) - **PHP Version**: >= 8.1 - **Runtime**: Swoole - **License**: Apache-2.0 --- ## Build/Lint/Test Commands ### Run All Tests ```bash composer test # or co-phpunit --prepend test/bootstrap.php --colors=always ``` ### Run Single Test ```bash # By test method name vendor/bin/phpunit --filter testExample # By fully qualified class name vendor/bin/phpunit --filter 'HyperfTest\\Cases\\ExampleTest::testExample' # By test class vendor/bin/phpunit test/Cases/ExampleTest.php ``` ### Code Style Fix ```bash # Fix all files composer cs-fix # Fix specific file php-cs-fixer fix app/Controller/IndexController.php # Dry run (check only) php-cs-fixer fix --dry-run --diff # Fix with config explicitly php-cs-fixer fix --config=.php-cs-fixer.php ``` ### Static Analysis (PHPStan) ```bash composer analyse # or vendor/bin/phpstan analyse --memory-limit 300M # With specific level vendor/bin/phpstan analyse --memory-limit 200M -l 5 ``` ### Start Development Server ```bash composer start # or php ./bin/hyperf.php start ``` --- ## Code Style Guidelines ### File Structure ### PSR Standards - **PSR-2**: Code must follow PSR-2 coding style - **PSR-4**: Autoloading via namespaces ### PHP CS Fixer Rules (from `.php-cs-fixer.php`) | Rule | Value | |------|-------| | Array syntax | Short: `[]` instead of `array()` | | List syntax | Short: `list($a, $b)` → `[$a, $b]` | | Concat space | One space around `.` | | Quote style | Single quotes | | Declare strict types | Required: `declare(strict_types=1);` | | Ordered imports | class → function → const | | Global namespace import | `use App\Foo;` (no leading `\`) | | Yoda style | Variable on right: `$value === self::FOO` | | Blank line before statement | Before `declare` | | Not operator | With successor space: `! $value` | | Constant case | Lower: `const FOO = 1;` | ### Imports Ordering ```php use App\Constants\ErrorCode; use Hyperf\Constants\AbstractConstants; use Hyperf\Constants\Annotation\Constants; use Hyperf\HttpServer\Contract\RequestInterface; use Psr\Container\ContainerInterface; #[Constants] class ErrorCode extends AbstractConstants { // ... } ``` ### Naming Conventions | Element | Convention | Example | |---------|------------|---------| | Namespace | PascalCase | `App\Controller`, `App\Constants` | | Class | PascalCase | `IndexController`, `BusinessException` | | Method | camelCase | `getUser()`, `handleMessage()` | | Property | camelCase | `$request`, `$container` | | Constant | SCREAMING_SNAKE | `SERVER_ERROR`, `DEFAULT_TIMEOUT` | | File | PascalCase.php | `ErrorCode.php`, `IndexController.php` | ### Type Declarations - Use strict types: `declare(strict_types=1);` - Use return type hints when possible - Use property type hints ```php class QueueHandleListener implements ListenerInterface { protected LoggerInterface $logger; public function __construct(ContainerInterface $container) { // ... } public function process(object $event): void { // ... } } ``` ### PHPDoc Annotations - Align PHPDoc annotations to the left - Do NOT use `@author` annotation - Use `@param` and `@return` with types ```php /** * @param int $code Error code * @param string|null $message Error message */ public function __construct(int $code = 0, string $message = null) ``` ### Dependency Injection Use `#[Inject]` attribute for automatic injection: ```php use Hyperf\Di\Annotation\Inject; class AbstractController { #[Inject] protected ContainerInterface $container; #[Inject] protected RequestInterface $request; } ``` ### Error Handling - Business exceptions: `App\Exception\BusinessException` - Extends `Hyperf\Server\Exception\ServerException` - Use Hyperf's `LoggerInterface` for logging - Use `ErrorCode::getMessage($code)` to get error messages ### Directory Structure ``` app/ ├── Constants/ # ErrorCode, system constants ├── Controller/ # HTTP controllers ├── Exception/ # Exception classes and handlers ├── Listener/ # Event listeners ├── Model/ # Database models └── Process/ # Custom processes test/ ├── bootstrap.php # Test bootstrap ├── Cases/ # Test cases └── HttpTestCase.php # HTTP test base class config/ ├── container.php # DI container config └── ... ``` ### Testing - Tests extend `Hyperf\Testing\TestCase` or `HyperfTest\HttpTestCase` - Test classes in `HyperfTest\*` namespace - Use `#[CoversNothing]` for unit tests without coverage - Use `$this->get()`, `$this->post()`, etc. for HTTP assertions ### Gitignore Patterns ``` vendor/ runtime/ .env .phpunit.cache/ ``` --- ## CI/CD The project uses GitHub Actions (see `.github/workflows/build.yml`). Docker build is triggered on push and pull requests. ## Additional Resources - [Hyperf Wiki](https://hyperf.wiki) - [Hyperf Documentation](https://hyperf.wiki) - [PSR-2 Coding Style Guide](https://www.php-fig.org/psr/psr-2/)