Структура PHP-приложения: как эффективно использовать возможности языка

Раздел: Программирование на PHP -> Структура приложения

Использование PHP в структуре приложения

Как организовать PHP-приложение с использованием современных стандартов?

Наиболее эффективным решением является использование автозагрузки классов через Composer по стандарту PSR-4. Это позволяет автоматически подключать классы без ручных require. Пример структуры:

myapp/
  src/
    Controllers/
      HomeController.php
    Models/
      User.php
  public/
    index.php
  composer.json

Php app uses (использование приложения php)

В composer.json указываем автозагрузку:

{
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    }
}

После запуска composer dump-autoload классы из пространства имен App будут найдены. В index.php достаточно написать:

require __DIR__ . '/../vendor/autoload.php';
use App\Controllers\HomeController;
$controller = new HomeController();
$controller->index();

Этот подход обеспечивает чистую архитектуру, легкость поддержки и возможность использовать сторонние библиотеки через Composer.

Типичные ошибки: неправильное указание пути в composer.json (директория должна соответствовать namespace), забыть запустить composer dump-autoload после изменения, конфликт пространств имен.
Решение: проверять, что регистр директорий совпадает с namespace, перезапускать автозагрузку.

Как соединить несколько файлов без использования классов?

Можно использовать require или include для подключения файлов. Структура:

myapp/
  includes/
    header.php
    footer.php
    functions.php
  index.php

В index.php:

<?
require 'includes/functions.php';
require 'includes/header.php';
echo '

Главная страница

'; require 'includes/footer.php';

Этот подход прост, но при росте приложения становится трудно поддерживать, возможны конфликты переменных.

Проблемы: нет контроля пространства имен, дублирование кода, сложность отладки.

Как организовать повторно используемые функции?

Создать файл с функциями, подключать его с require_once, чтобы избежать повторного подключения. Пример:

<? // helpers.php
function sanitize($data) { ... }
function redirect($url) { ... }

В index.php: require_once 'helpers.php';

Ошибка: использование require вместо require_once может вызвать ошибку повторного объявления функции.

Как быстро создать REST API на PHP?

Установка через Composer: composer require slim/slim. Пример маршрута:

use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;

require 'vendor/autoload.php';
$app = AppFactory::create();
$app->get('/hello/{name}', function (Request $request, Response $response, $args) {
    $name = $args['name'];
    $response->getBody()->write("Hello $name");
    return $response;
});
$app->run();

Запуск: php -S localhost:8080 -t public

Проблемы: требуется понимание PSR-7, сложность настройки для новичков.

Как отделить HTML от PHP кода?

Установка: composer require twig/twig. Создание шаблона:

// index.php
require 'vendor/autoload.php';
$loader = new \Twig\Loader\FilesystemLoader('templates');
$twig = new \Twig\Environment($loader);
echo $twig->render('home.html.twig', ['name' => 'Мир']);

Шаблон home.html.twig: <h1>Привет, {{ name }}!</h1>

Ошибка: неправильный путь к шаблонам, отсутствие расширения .twig.

Расширенные примеры организации приложения

Пример 1: Простое MVC приложение с собственным роутером.

Структура:

Пример
app/
  core/
    Router.php
    Controller.php
  controllers/
    HomeController.php
  models/
    User.php
  views/
    home.php
public/
  index.php
.htaccess
composer.json

index.php:

Пример
require __DIR__ . '/../vendor/autoload.php';
$router = new App\Core\Router();
$router->add('GET', '/', 'HomeController@index');
$router->dispatch();

Router.php:

Пример
namespace App\Core;
class Router {
    private $routes = [];
    public function add($method, $path, $handler) {
        $this->routes[] = compact('method', 'path', 'handler');
    }
    public function dispatch() {
        $requestMethod = $_SERVER['REQUEST_METHOD'];
        $requestUri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
        foreach ($this->routes as $route) {
            if ($route['method'] === $requestMethod && $route['path'] === $requestUri) {
                list($class, $method) = explode('@', $route['handler']);
                $class = "App\\Controllers\\$class";
                $controller = new $class();
                $controller->$method();
                return;
            }
        }
        http_response_code(404);
        echo '404 Not Found';
    }
}

HomeController:

Пример
namespace App\Controllers;
class HomeController {
    public function index() {
        $userModel = new \App\Models\User();
        $users = $userModel->getAll();
        require __DIR__ . '/../views/home.php';
    }
}

User model:

Пример
namespace App\Models;
use PDO;
class User {
    private $db;
    public function __construct() {
        $this->db = new PDO('mysql:host=localhost;dbname=test', 'root', '');
    }
    public function getAll() {
        $stmt = $this->db->query('SELECT * FROM users');
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
}

View home.php:

Пример

Список пользователей

    <? foreach ($users as $user): ?>
  • <?= htmlspecialchars($user['name']) ?>
  • <? endforeach; ?>

Результат при обращении к /: выведет список пользователей из БД. Если БД не настроена, будет ошибка подключения.

Ошибка: отсутствие PDO драйвера, неправильные учетные данные. Решение: проверить наличие расширения pdo_mysql в php.ini.

Пример 2: REST API с JSON ответом на чистом PHP (без фреймворка).

Пример
<?
// api/index.php
header('Content-Type: application/json');
$method = $_SERVER['REQUEST_METHOD'];
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$parts = explode('/', trim($uri, '/'));
$resource = $parts[0] ?? '';
$id = $parts[1] ?? null;

$data = ['message' => 'Hello API'];
if ($method === 'GET' && $resource === 'users') {
    $data = [['id'=>1, 'name'=>'Alice'], ['id'=>2, 'name'=>'Bob']];
} elseif ($method === 'POST' && $resource === 'users') {
    $input = json_decode(file_get_contents('php://input'), true);
    $data = ['created' => $input];
}
echo json_encode($data, JSON_UNESCAPED_UNICODE);

Запуск: php -S localhost:8080 -t api/

Результат запроса GET /users:

[{"id":1,"name":"Alice"},{"id":2,"name":"Bob"}]

Результат POST /users с телом {"name":"Charlie"}:

{"created":{"name":"Charlie"}}

Пример 3: Использование шаблонизатора Twig с наследованием.

Создаем base.html.twig:

Пример
<!DOCTYPE html>
<html><head><title>{% block title %}{% endblock %}</title></head>
<body>{% block content %}{% endblock %}</body></html>

page.html.twig:

Пример
{% extends "base.html.twig" %}
{% block title %}Главная{% endblock %}
{% block content %}<h1>Привет, {{ name }}</h1>{% endblock %}

PHP код:

Пример
$loader = new \Twig\Loader\FilesystemLoader('templates');
$twig = new \Twig\Environment($loader);
echo $twig->render('page.html.twig', ['name' => 'Мир']);

Результат: HTML с заголовком "Главная" и телом "Привет, Мир".

Использование приложения PHP - comments

En
Php app uses (php)