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.

rulespsr-file-structure.md

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

File Structure

Organize PHP files with proper ordering of elements and logical grouping.

Bad Example

<?php
class UserService {
use LoggableTrait;
private $repo;
const MAX = 100;
public function find($id) {}
private $logger;
public const MIN = 1;
public function __construct($repo, $logger) {
$this->repo = $repo;
$this->logger = $logger;
}
}
namespace App\Services;
use App\Repositories\UserRepository;

Good Example

<?php

/**
 * This file is part of the MyApp package.
 *
 * (c) Company Name <email@example.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

declare(strict_types=1);

namespace App\Services;

use App\Contracts\UserServiceInterface;
use App\Domain\User\User;
use App\Domain\User\UserRepository;
use App\Events\UserCreated;
use DateTimeImmutable;
use InvalidArgumentException;
use Psr\EventDispatcher\EventDispatcherInterface;
use Psr\Log\LoggerInterface;

/**
 * Handles user-related business operations.
 */
final class UserService implements UserServiceInterface
{
    use LoggableTrait;
    use CacheableTrait;

    // Constants - public first, then protected, then private
    public const DEFAULT_PAGE_SIZE = 20;
    public const MAX_PAGE_SIZE = 100;
    protected const CACHE_TTL = 3600;
    private const LOG_CHANNEL = 'user';

    // Properties - ordered by visibility
    public readonly string $version;
    protected EventDispatcherInterface $dispatcher;
    private UserRepository $repository;
    private LoggerInterface $logger;
    private array $cache = [];

    // Constructor
    public function __construct(
        UserRepository $repository,
        LoggerInterface $logger,
        EventDispatcherInterface $dispatcher,
    ) {
        $this->repository = $repository;
        $this->logger = $logger;
        $this->dispatcher = $dispatcher;
        $this->version = '1.0.0';
    }

    // Public methods
    public function find(int $id): ?User
    {
        return $this->repository->find($id);
    }

    public function findOrFail(int $id): User
    {
        $user = $this->find($id);

        if ($user === null) {
            throw new UserNotFoundException($id);
        }

        return $user;
    }

    public function create(array $data): User
    {
        $this->validateCreateData($data);

        $user = $this->repository->create($data);

        $this->dispatcher->dispatch(
            new UserCreated($user->getId(), new DateTimeImmutable())
        );

        return $user;
    }

    public function update(User $user, array $data): User
    {
        $this->validateUpdateData($data);

        return $this->repository->update($user, $data);
    }

    public function delete(User $user): void
    {
        $this->repository->delete($user);
    }

    // Protected methods
    protected function getCacheKey(int $id): string
    {
        return sprintf('user:%d', $id);
    }

    // Private methods
    private function validateCreateData(array $data): void
    {
        if (empty($data['email'])) {
            throw new InvalidArgumentException('Email is required');
        }

        if (empty($data['name'])) {
            throw new InvalidArgumentException('Name is required');
        }
    }

    private function validateUpdateData(array $data): void
    {
        // Validation logic
    }
}

Standard File Structure Order

1. Opening PHP tag (<?php)
2. File-level docblock (optional - license, copyright)
3. declare(strict_types=1)
4. Blank line
5. namespace declaration
6. Blank line
7. use statements (grouped and sorted)
   - PHP native classes
   - External packages
   - Internal project classes
8. Blank line
9. Class/Interface/Trait/Enum docblock
10. Class/Interface/Trait/Enum declaration
    a. Traits (use statements)
    b. Constants (public → protected → private)
    c. Properties (public → protected → private)
    d. Constructor
    e. Public methods
    f. Protected methods
    g. Private methods

Use Statement Organization

<?php

declare(strict_types=1);

namespace App\Services;

// PHP native classes
use DateTimeImmutable;
use InvalidArgumentException;
use RuntimeException;

// External packages (alphabetized by vendor)
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;

// Internal project classes (alphabetized by namespace)
use App\Contracts\ServiceInterface;
use App\Domain\User\User;
use App\Domain\User\UserRepository;
use App\Events\UserCreated;
use App\Exceptions\UserNotFoundException;

Why

  • Predictability: Developers know where to find things
  • Readability: Logical ordering improves code comprehension
  • Maintenance: Consistent structure makes updates easier
  • Code Review: Standard format reduces review friction
  • Tooling: IDE and static analysis tools work better
  • PSR Compliance: Follows PHP-FIG recommendations

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