← Назад к вопросам

Как структурировать PHP-проект?

2.3 Middle🔥 291 комментариев
#PHP Core

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI7 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Структура PHP-проекта: современный подход

Структура PHP-проекта определяет его масштабируемость, тестируемость и поддерживаемость. В отличие устаревших подходов с единой папкой src, современные проекты следуют принципам чистой архитектуры и Domain-Driven Design (DDD). Я рекомендую следующую структуру для enterprise-приложений:

1. Ключевые директории проекта

project/
├── app/
│   ├── Domain/          # Ядро бизнес-логики
│   ├── Application/     # Слой применения бизнес-правил
│   ├── Infrastructure/  # Реализации внешних зависимостей
│   └── Presentation/    # Контроллеры, API endpoints
├── config/              # Конфигурации, параметры окружения
├── public/              # Публичные файлы, index.php
├── tests/               # Unit, Integration, Functional тесты
├── resources/           # Шаблоны, переводы, assets
├── storage/            # Генерируемые файлы (лог, cache)
├── vendor/             # Composer зависимости
├── docker/             # Docker конфигурации
└── database/           # Migrations, seeds

2. Детализация слоев архитектуры

Domain Layer (Ядро бизнес-логики)

// app/Domain/User/Entities/User.php
namespace App\Domain\User\Entities;

class User {
    private string $id;
    private string $email;
    
    public function changeEmail(string $email): void {
        // Бизнес-правила валидации email
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            throw new InvalidEmailException();
        }
        $this->email = $email;
    }
}
  • Entities: Основные бизнес-объекты с уникальной идентификацией
  • Value Objects: Объекты без идентификатора (Email, Money)
  • Aggregates: Группы связанных Entities
  • Repositories Interfaces: Абстракции для доступа к данным
  • Domain Events: События бизнес-процессов

Application Layer (Координация бизнес-процессов)

// app/Application/User/Commands/ChangeEmailCommand.php
namespace App\Application\User\Commands;

class ChangeEmailCommandHandler {
    public function __construct(
        private UserRepositoryInterface $repository
    ) {}
    
    public function handle(ChangeEmailCommand $command): void {
        $user = $this->repository->find($command->userId);
        $user->changeEmail($command->newEmail);
        $this->repository->save($user);
    }
}
  • Commands/CQRS: Команды для изменения состояния
  • Queries: Запросы для чтения данных
  • DTOs: Data Transfer Objects для передачи данных между слоями
  • Services: Координация нескольких Domain объектов

Infrastructure Layer (Внешние реализации)

// app/Infrastructure/Persistence/Doctrine/UserRepository.php
namespace App\Infrastructure\Persistence\Doctrine;

class UserRepository implements UserRepositoryInterface {
    public function find(string $id): User {
        // Doctrine, Eloquent или другой ORM
        return $this->entityManager->find(User::class, $id);
    }
}
  • Persistence: Реализации Repository (Doctrine, Eloquent)
  • External Services: Клиенты API, интеграции
  • Messaging: Реализации событий (RabbitMQ, Kafka)
  • File Storage: Адаптеры для S3, локального хранилища

3. Критические принципы организации

  • Инверсия зависимостей: Слои Domain и Application НЕ зависят от Infrastructure
  • Следование SOLID: Каждый класс имеет одну ответственность
  • Тестируемость: Domain и Application слои тестируются без внешних зависимостей
  • Модульность: Группировка по бизнес-контекстам (User, Order, Payment)

4. Практические рекомендации

  • Используйте Composer для управления зависимостями и автозагрузки (PSR-4)
  • Разделите конфигурации по окружениям (local, production, testing)
  • Применяйте миграции базы данных для контроля схемы данных
  • Следуйте PSR стандартам для кодирования, автозагрузки, логгирования
  • Используйте Docker для унификации окружения разработки

5. Пример реальной структуры с маршрутизацией

// public/index.php - единая точка входа
require __DIR__ . '/../vendor/autoload.php';

$container = require __DIR__ . '/../config/container.php';
$router = require __DIR__ . '/../config/routes.php';

$request = Laminas\Diactoros\ServerRequestFactory::fromGlobals();
$response = $router->dispatch($request, $container);

Такая структура позволяет:

  1. Изолировать бизнес-логику от фреймворков и инфраструктуры
  2. Легко заменять реализации (ORM, кеш, файловое хранилище)
  3. Эффективно тестировать каждый компонент отдельно
  4. Адаптироваться к изменениям требований бизнеса
  5. Сокращать coupling между модулями системы

Выбор структуры зависит от размера проекта: для небольших приложений можно использовать simplified MVC, но для enterprise-систем чистая архитектура становится обязательной.