All skills
jeffallan avatar

/php-pro

@efebc44
by jeffallanjeffallan/claude-skills12k stars
1,124

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.

Use this Skill: https://skilld.dev/gh/jeffallan/claude-skills/php-pro

This session only. Nothing lands on disk.

referencesmodern-php-features.md

≈1.6k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Modern PHP 8.3+ Features

Strict Types & Type Declarations

<?php

declare(strict_types=1);

namespace App\Domain\User;

final readonly class User
{
    public function __construct(
        public int $id,
        public string $email,
        public UserStatus $status,
        public \DateTimeImmutable $createdAt,
    ) {}
}

function calculateTotal(int $price, float $taxRate): float
{
    return $price * (1 + $taxRate);
}

// Union types
function processId(int|string $id): string
{
    return is_int($id) ? (string)$id : $id;
}

// Intersection types
interface Timestamped {}
interface Authenticatable {}

function handleUser(Timestamped&Authenticatable $user): void {}

Enums with Methods

<?php

declare(strict_types=1);

enum UserStatus: string
{
    case ACTIVE = 'active';
    case SUSPENDED = 'suspended';
    case DELETED = 'deleted';

    public function label(): string
    {
        return match($this) {
            self::ACTIVE => 'Active User',
            self::SUSPENDED => 'Suspended',
            self::DELETED => 'Deleted User',
        };
    }

    public function canLogin(): bool
    {
        return $this === self::ACTIVE;
    }

    public static function fromString(string $value): self
    {
        return self::from(strtolower($value));
    }
}

enum HttpStatus: int
{
    case OK = 200;
    case CREATED = 201;
    case BAD_REQUEST = 400;
    case UNAUTHORIZED = 401;
    case NOT_FOUND = 404;
    case SERVER_ERROR = 500;

    public function isSuccess(): bool
    {
        return $this->value >= 200 && $this->value < 300;
    }
}

Readonly Properties & Classes

<?php

declare(strict_types=1);

// Readonly class (PHP 8.2+)
final readonly class Money
{
    public function __construct(
        public int $amount,
        public string $currency,
    ) {
        if ($amount < 0) {
            throw new \InvalidArgumentException('Amount cannot be negative');
        }
    }

    public function add(Money $other): self
    {
        if ($this->currency !== $other->currency) {
            throw new \InvalidArgumentException('Currency mismatch');
        }
        return new self($this->amount + $other->amount, $this->currency);
    }
}

// Individual readonly properties
class Configuration
{
    public function __construct(
        public readonly string $apiKey,
        public readonly string $apiSecret,
        private string $cache = '',
    ) {}
}

Attributes (Metadata)

<?php

declare(strict_types=1);

#[\Attribute(\Attribute::TARGET_CLASS)]
final readonly class Route
{
    public function __construct(
        public string $path,
        public string $method = 'GET',
        public array $middleware = [],
    ) {}
}

#[\Attribute(\Attribute::TARGET_PROPERTY)]
final readonly class Validate
{
    public function __construct(
        public ?string $rule = null,
        public ?int $min = null,
        public ?int $max = null,
    ) {}
}

// Using attributes
#[Route('/api/users', method: 'POST', middleware: ['auth'])]
final class CreateUserController
{
    public function __invoke(CreateUserRequest $request): JsonResponse
    {
        // ...
    }
}

class UserDto
{
    #[Validate(rule: 'email')]
    public string $email;

    #[Validate(min: 8, max: 100)]
    public string $password;
}

First-Class Callables

<?php

declare(strict_types=1);

class UserService
{
    public function findById(int $id): ?User {}
    public function create(array $data): User {}
}

$service = new UserService();

// PHP 8.1+ first-class callable syntax
$finder = $service->findById(...);
$user = $finder(42);

// Array operations
$numbers = [1, 2, 3, 4, 5];
$doubled = array_map(fn($n) => $n * 2, $numbers);

// Named arguments with callable
$result = array_filter(
    array: $numbers,
    callback: fn($n) => $n % 2 === 0,
);

Match Expressions

<?php

declare(strict_types=1);

function getStatusColor(UserStatus $status): string
{
    return match ($status) {
        UserStatus::ACTIVE => 'green',
        UserStatus::SUSPENDED => 'yellow',
        UserStatus::DELETED => 'red',
    };
}

function calculateShipping(int $weight, string $zone): float
{
    return match (true) {
        $weight < 1000 => 5.00,
        $weight < 5000 && $zone === 'local' => 10.00,
        $weight < 5000 => 15.00,
        default => 25.00,
    };
}

// Match with multiple conditions
function getHttpMessage(int $code): string
{
    return match ($code) {
        200, 201, 204 => 'Success',
        400, 422 => 'Client Error',
        401, 403 => 'Unauthorized',
        500, 502, 503 => 'Server Error',
        default => 'Unknown',
    };
}

Fibers (PHP 8.1+)

<?php

declare(strict_types=1);

// Basic fiber example
$fiber = new \Fiber(function (): void {
    $value = \Fiber::suspend('fiber started');
    echo "Received: {$value}\n";
    \Fiber::suspend('second suspend');
    echo "Fiber completed\n";
});

$result1 = $fiber->start();
echo "First result: {$result1}\n";

$result2 = $fiber->resume('data from main');
echo "Second result: {$result2}\n";

$fiber->resume('final data');

// Async-style with fibers
function async(callable $callback): \Fiber
{
    return new \Fiber($callback);
}

function await(\Fiber $fiber): mixed
{
    if (!$fiber->isStarted()) {
        return $fiber->start();
    }
    return $fiber->resume();
}

Never Type

<?php

declare(strict_types=1);

function redirect(string $url): never
{
    header("Location: {$url}");
    exit;
}

function abort(int $code, string $message): never
{
    http_response_code($code);
    echo json_encode(['error' => $message]);
    exit;
}

class NotFoundException extends \Exception
{
    public static function throw(string $resource): never
    {
        throw new self("Resource not found: {$resource}");
    }
}

Quick Reference

Feature PHP Version Usage
Readonly properties 8.1+ public readonly string $name
Readonly classes 8.2+ readonly class User {}
Enums 8.1+ enum Status: string {}
First-class callables 8.1+ $fn = $obj->method(...)
Never type 8.1+ function exit(): never
Fibers 8.1+ new \Fiber(fn() => ...)
Pure intersection types 8.1+ A&B $param
DNF types 8.2+ (A&B)|C $param
Constants in traits 8.2+ trait T { const X = 1; }

Source: SKILL.md on GitHub

1 alert16d5 checks · Risk CRITICAL
  • Gen Agent Trust Hub16d

    This skill provides a comprehensive environment for senior PHP development, including patterns for Laravel, Symfony, and asynchronous programming with Swoole and ReactPHP. While automated scanners flagged the documentation link and SKILL.md file, manual analysis indicates the content consists of standard enterprise PHP development patterns and references to the author's own GitHub documentation pages.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer6mo

    6 files scanned · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at efebc44. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Steadyupdated 5 months ago
Other metadata
metadata
{
  "author": "https://github.com/Jeffallan",
  "version": "1.1.0",
  "domain": "language",
  "triggers": "PHP, Laravel, Symfony, Composer, PHPStan, PSR, PHP API, Eloquent, Doctrine",
  "role": "specialist",
  "scope": "implementation",
  "output-format": "code",
  "related-skills": "fullstack-guardian, fastapi-expert"
}
  • Testing
  • php
  • laravel
  • symfony
  • phpstan
  • orm
  • dependency-injection
  • rest-api
  • graphql
  • typed-dto

README badge

README badge for jeffallan/claude-skills/php-pro

Writes PHP 8.3+ code with strict typing, PHPStan level 9 validation, and enterprise patterns for Laravel or Symfony. Generates typed DTOs, services with dependency injection, controllers, migrations, and PHPUnit/Pest tests enforcing 80%+ coverage before delivery.

Generated from the current SKILL.md.

Does this skill support PHP versions before 8.3?
No. PHP Pro requires PHP 8.3+ and enforces modern language features like readonly properties, enums, and strict typing.
What frameworks does this skill work with?
Laravel and Symfony are the primary targets. The skill includes reference guides for both frameworks' patterns (services, repositories, DI, events, commands).
Does this skill enforce static analysis?
Yes. PHPStan level 9 is mandatory before delivery, and all code must pass with zero errors. Tests must achieve 80%+ coverage.
Can this skill set up async code?
Yes. The skill includes patterns for Swoole, ReactPHP, and fibers for async PHP workflows.
What testing frameworks does this skill use?
PHPUnit and Pest. The skill includes test structure templates and enforces 80%+ code coverage before delivery.

Generated from the current SKILL.md. These answers refresh after source changes.