All skills
asyrafhussin avatar

/php-best-practices

@e7ea05d

PHP 8.x modern patterns, PSR standards, and SOLID principles. Use when reviewing PHP code, checking type safety, auditing code quality, or ensuring PHP best practices. Triggers on "review PHP", "check PHP code", "audit PHP", or "PHP best practices".

Use this Skill: https://skilld.dev/gh/asyrafhussin/agent-skills/php-best-practices

This session only. Nothing lands on disk.

rulesmodern-attributes.md

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

PHP Attributes

Use native attributes for metadata instead of docblock annotations (PHP 8.0+).

Bad Example

<?php

declare(strict_types=1);

// Using docblock annotations - parsed as strings, no type safety
class UserController
{
    /**
     * @Route("/users/{id}", methods={"GET"})
     * @Cache(maxage=3600)
     * @Security("is_granted('VIEW', user)")
     */
    public function show(int $id)
    {
        // Annotations are just comments - no IDE support for validation
    }
}

// Validation using docblocks
class CreateUserRequest
{
    /**
     * @Assert\NotBlank()
     * @Assert\Email()
     */
    public string $email;

    /**
     * @Assert\NotBlank()
     * @Assert\Length(min=8)
     */
    public string $password;
}

Good Example

<?php

declare(strict_types=1);

// Define custom attributes
#[Attribute(Attribute::TARGET_METHOD)]
class Route
{
    public function __construct(
        public string $path,
        public array $methods = ['GET'],
        public ?string $name = null,
    ) {}
}

#[Attribute(Attribute::TARGET_METHOD)]
class Cache
{
    public function __construct(
        public int $maxAge = 0,
        public bool $public = true,
    ) {}
}

#[Attribute(Attribute::TARGET_PROPERTY)]
class Validate
{
    public function __construct(
        public array $rules = [],
    ) {}
}

#[Attribute(Attribute::TARGET_CLASS)]
class Entity
{
    public function __construct(
        public string $table,
    ) {}
}

#[Attribute(Attribute::TARGET_PROPERTY)]
class Column
{
    public function __construct(
        public string $name,
        public string $type = 'string',
        public bool $nullable = false,
    ) {}
}

// Using attributes on a controller
class UserController
{
    #[Route('/users/{id}', methods: ['GET'], name: 'user.show')]
    #[Cache(maxAge: 3600)]
    public function show(int $id): Response
    {
        return new Response($this->userService->find($id));
    }

    #[Route('/users', methods: ['POST'], name: 'user.create')]
    public function create(CreateUserRequest $request): Response
    {
        return new Response($this->userService->create($request));
    }
}

// Using attributes for validation
class CreateUserRequest
{
    #[Validate(rules: ['required', 'email', 'unique:users'])]
    public string $email;

    #[Validate(rules: ['required', 'min:8', 'confirmed'])]
    public string $password;

    #[Validate(rules: ['required', 'string', 'max:255'])]
    public string $name;
}

// Entity with ORM attributes
#[Entity(table: 'users')]
class User
{
    #[Column(name: 'id', type: 'integer')]
    public int $id;

    #[Column(name: 'email', type: 'string')]
    public string $email;

    #[Column(name: 'created_at', type: 'datetime', nullable: true)]
    public ?DateTimeImmutable $createdAt;
}

// Reading attributes via reflection
function getRoutes(object $controller): array
{
    $routes = [];
    $reflection = new ReflectionClass($controller);

    foreach ($reflection->getMethods() as $method) {
        $attributes = $method->getAttributes(Route::class);
        foreach ($attributes as $attribute) {
            $route = $attribute->newInstance();
            $routes[] = [
                'path' => $route->path,
                'methods' => $route->methods,
                'handler' => [$controller, $method->getName()],
            ];
        }
    }

    return $routes;
}

Why

  • Type Safety: Attributes are real classes with typed constructors
  • IDE Support: Full autocompletion, refactoring, and navigation
  • Validation: Invalid attribute usage caught by static analysis tools
  • Native Feature: Built into PHP, no external parser needed
  • Performance: Faster than parsing docblocks at runtime
  • Named Arguments: Clear parameter names in attribute usage

Source: SKILL.md on GitHub

No alerts17d5 checks · Risk SAFE
  • Gen Agent Trust Hub17d

    This skill is a comprehensive and safe resource for PHP 8.x best practices. It provides structured guidance on type safety, modern PHP syntax, PSR standards, and secure coding practices (such as prepared statements and password hashing). The agent is instructed to use standard environment detection commands (php -v, grep) to tailor its advice. No malicious patterns or security risks were identified.

  • Socket17d

    No alerts

  • Snyk17d

    Risk: LOW · No issues

  • Runlayer6mo

    39 files scanned · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

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

Last checked against GitHub last month.

Steadyupdated 7 months ago
Other metadata
metadata
{
  "author": "php-community",
  "version": "2.1.0",
  "phpVersion": "8.0 - 8.5"
}

README badge

README badge for asyrafhussin/agent-skills/php-best-practices