Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Use when building PHP applications with modern PHP 8.3+ features, Laravel, or Symfony frameworks. Invokes strict typing, PHPStan level 9, async patterns with Swoole, and PSR standards. Creates controllers, configures middleware, generates migrations, writes PHPUnit/Pest tests, defines typed DTOs and value objects, sets up dependency injection, and scaffolds REST/GraphQL APIs. Use when working with Eloquent, Doctrine, Composer, Psalm, ReactPHP, or any PHP API development.
.claude/skills/jeffallan-php-pro/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | -5% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 29% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 297% | 0% |
| case-05 | ✗→✓ | ▲ Improved | -8% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 53% | 0% |
Senior PHP developer with deep expertise in PHP 8.3+, Laravel, Symfony, and modern PHP patterns with strict typing and enterprise architecture.
vendor/bin/phpstan analyse --level=9; fix all errors before proceeding. Run vendor/bin/phpunit or vendor/bin/pest; enforce 80%+ coverage. Only deliver when both pass clean.Load detailed guidance based on context:
| Topic | Reference | Load When | |-------|-----------|-----------| | Modern PHP | references/modern-php-features.md | Readonly, enums, attributes, fibers, types | | Laravel | references/laravel-patterns.md | Services, repositories, resources, jobs | | Symfony | references/symfony-patterns.md | DI, events, commands, voters | | Async PHP | references/async-patterns.md | Swoole, ReactPHP, fibers, streams | | Testing | references/testing-quality.md | PHPUnit, PHPStan, Pest, mocking |
declare(strict_types=1))Every complete implementation delivers: a typed entity/DTO, a service class, and a test. Use these as the baseline structure.
php<?php declare(strict_types=1); namespace App\DTO; final readonly class CreateUserDTO { public function __construct( public string $name, public string $email, public string $password, ) {} public static function fromArray(array $data): self { return new self( name: $data['name'], email: $data['email'], password: $data['password'], ); } }
php<?php declare(strict_types=1); namespace App\Services; use App\DTO\CreateUserDTO; use App\Models\User; use App\Repositories\UserRepositoryInterface; use Illuminate\Support\Facades\Hash; final class UserService { public function __construct( private readonly UserRepositoryInterface $users, ) {} public function create(CreateUserDTO $dto): User { return $this->users->create([ 'name' => $dto->name, 'email' => $dto->email, 'password' => Hash::make($dto->password), ]); } }
php<?php declare(strict_types=1); namespace Tests\Unit\Services; use App\DTO\CreateUserDTO; use App\Models\User; use App\Repositories\UserRepositoryInterface; use App\Services\UserService; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; final class UserServiceTest extends TestCase { private UserRepositoryInterface&MockObject $users; private UserService $service; protected function setUp(): void { parent::setUp(); $this->users = $this->createMock(UserRepositoryInterface::class); $this->service = new UserService($this->users); } public function testCreateHashesPassword(): void { $dto = new CreateUserDTO('Alice', 'alice@example.com', 'secret'); $user = new User(['name' => 'Alice', 'email' => 'alice@example.com']); $this->users ->expects($this->once()) ->method('create') ->willReturn($user); $result = $this->service->create($dto); $this->assertSame('Alice', $result->name); } }
php<?php declare(strict_types=1); namespace App\Enums; enum UserStatus: string { case Active = 'active'; case Inactive = 'inactive'; case Banned = 'banned'; public function label(): string { return match($this) { self::Active => 'Active', self::Inactive => 'Inactive', self::Banned => 'Banned', }; } }
When implementing a feature, deliver in this order:
PHP 8.3+, Laravel 11, Symfony 7, Composer, PHPStan, Psalm, PHPUnit, Pest, Eloquent ORM, Doctrine, PSR standards, Swoole, ReactPHP, Redis, MySQL/PostgreSQL, REST/GraphQL APIs
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 23,728 | 18,509 | -22% | 1 | 1 | 0% | 6,204 | 5,902 | -5% | 0 | 0 | — |
case-02 | fail→fail | 26,529 | 21,408 | -19% | 1 | 1 | 0% | 6,197 | 6,084 | -2% | 0 | 0 | — |
case-03 | fail→pass | 19,077 | 18,080 | -5% | 1 | 1 | 0% | 4,257 | 5,510 | +29% | 0 | 0 | — |
case-04 | fail→pass | 2,849 | 3,495 | +23% | 1 | 1 | 0% | 518 | 2,055 | +297% | 0 | 0 | — |
case-05 | fail→pass | 12,796 | 3,666 | -71% | 1 | 1 | 0% | 2,105 | 1,928 | -8% | 0 | 0 | — |
case-06 | fail→pass | 11,150 | 10,293 | -8% | 1 | 1 | 0% | 2,173 | 3,335 | +53% | 0 | 0 | — |
case-07 | pass→pass | 5,808 | 5,684 | -2% | 1 | 1 | 0% | 1,052 | 2,531 | +141% | 0 | 0 | — |
case-08 | pass→pass | 10,294 | 12,834 | +25% | 1 | 1 | 0% | 1,989 | 3,913 | +97% | 0 | 0 | — |
case-09 | pass→pass | 2,972 | 1,906 | -36% | 1 | 1 | 0% | 535 | 1,694 | +217% | 0 | 0 | — |
case-10 | pass→pass | 6,134 | 7,626 | +24% | 1 | 1 | 0% | 1,395 | 2,875 | +106% | 0 | 0 | — |
case-11 | pass→pass | 14,415 | 13,118 | -9% | 1 | 1 | 0% | 2,907 | 3,876 | +33% | 0 | 0 | — |
case-12 | pass→pass | 11,113 | 11,658 | +5% | 1 | 1 | 0% | 2,227 | 3,753 | +69% | 0 | 0 | — |
case-13 | pass→pass | 13,258 | 10,859 | -18% | 1 | 1 | 0% | 2,107 | 3,475 | +65% | 0 | 0 | — |
case-14 | pass→pass | 11,124 | 8,496 | -24% | 1 | 1 | 0% | 2,019 | 3,369 | +67% | 0 | 0 | — |
case-15 | fail→pass | 16,968 | 2,793 | -84% | 1 | 1 | 0% | 1,522 | 1,856 | +22% | 0 | 0 | — |
case-16 | pass→pass | 5,321 | 4,765 | -10% | 1 | 1 | 0% | 872 | 2,072 | +138% | 0 | 0 | — |
case-17 | pass→pass | 11,332 | 12,509 | +10% | 1 | 1 | 0% | 2,156 | 3,530 | +64% | 0 | 0 | — |
case-18 | pass→pass | 14,639 | 12,474 | -15% | 1 | 1 | 0% | 2,402 | 3,825 | +59% | 0 | 0 | — |
case-19 | pass→pass | 5,034 | 5,402 | +7% | 1 | 1 | 0% | 930 | 2,389 | +157% | 0 | 0 | — |
case-20 | pass→pass | 15,071 | 17,114 | +14% | 1 | 1 | 0% | 2,962 | 4,852 | +64% | 0 | 0 | — |
case-21 | pass→pass | 17,894 | 17,830 | -0% | 1 | 1 | 0% | 2,933 | 4,900 | +67% | 0 | 0 | — |
case-22 | fail→pass | 7,906 | 1,619 | -80% | 1 | 1 | 0% | 1,398 | 1,659 | +19% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +32 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.