Назначение index.php в PHP-проектах

Раздел: Веб-разработка на PHP -> Структура веб-приложений

Файл index.php: точка входа в веб-приложение

Файл index.php является точкой входа для большинства PHP-приложений. Веб-сервер (например, Apache или Nginx) настраивается так, чтобы при обращении к корню сайта или к любому маршруту через механизм URL rewriting, исполнялся именно этот файл. Он принимает HTTP-запрос, инициализирует приложение и возвращает ответ. В этой статье рассматриваются различные способы организации index.php - от простейших до используемых в современных фреймворках.

Основное решение: минимальный index.php

Простейший index.php содержит логику обработки запроса напрямую. Он подходит для небольших проектов без маршрутизации.


<?php
// index.php - простейшая точка входа
echo "Привет, мир!";
?>

Html php file (html и php файлы)

Этот код выводит статическую строку. Для динамических данных можно подключать другие файлы:


<?php
require 'config.php';
$page = $_GET['page'] ?? 'home';
$content = getPageContent($page);
echo $content;
?>

Index php file (файл index.php)

Однако такой подход быстро становится запутанным при росте приложения.

Варианты реализации index.php

Как создать простейшую точку входа с базовой маршрутизацией?

Если требуется обрабатывать несколько страниц, можно добавить простой роутинг через $_GET или $_SERVER['REQUEST_URI'].


<?php
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

if ($uri === '/' || $uri === '/home') {
    echo 'Домашняя страница';
} elseif ($uri === '/about') {
    echo 'О нас';
} else {
    http_response_code(404);
    echo 'Страница не найдена';
}
?>

Проблема:

При добавлении десятков страниц код становится громоздким. Кроме того, не обрабатываются POST-запросы и параметры URL. Решение: использовать switch или массив маршрутов.

Как организовать маршрутизацию с помощью switch?


<?php
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

switch($path) {
    case '/':
        $controller = 'HomeController';
        break;
    case '/about':
        $controller = 'AboutController';
        break;
    default:
        $controller = 'NotFoundController';
}

require "controllers/{$controller}.php";
$instance = new $controller();
echo $instance->render();
?>

Ошибка:

Если имя контроллера небезопасно, возможны атаки path traversal. Нужно проверять, что файл существует и имя допустимо.

Как реализовать фронт-контроллер с автозагрузкой классов?

Современный подход - использование единого фронт-контроллера, который загружает классы через Composer и передаёт управление роутеру.


<?php
require __DIR__ . '/vendor/autoload.php';

$router = new App\Router();
$router->add('/', 'HomeController@index');
$router->add('/about', 'AboutController@index');

$response = $router->dispatch($_SERVER['REQUEST_URI']);
echo $response;
?>

Типичная ошибка:

Отсутствие автозагрузки ведёт к ошибкам require. Нужно настроить composer.json и выполнить composer install.

Как index.php выглядит в фреймворках (Laravel, Symfony)?

Фреймворки используют продвинутые фронт-контроллеры. Например, в Laravel файл public/index.php:


<?php
define('LARAVEL_START', microtime(true));

require __DIR__.'/../vendor/autoload.php';

$app = require_once __DIR__.'/../bootstrap/app.php';

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);

$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);

$response->send();

$kernel->terminate($request, $response);
?>

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

Расширенные примеры использования index.php

Пример 1: Простой роутер с поддержкой параметров

Пример

<?php
// index.php
require 'vendor/autoload.php';

$router = new Router();

$router->add('GET', '/user/{id}', function($id) {
    return "Профиль пользователя #$id";
});

$router->add('POST', '/submit', function() {
    return 'Данные отправлены';
});

$method = $_SERVER['REQUEST_METHOD'];
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

$response = $router->resolve($method, $uri);

echo $response;
?>
При запросе GET /user/42: "Профиль пользователя #42"
При запросе POST /submit: "Данные отправлены"
При неизвестном маршруте: 404 страница

Пример 2: Обработка ошибок и логирование в index.php

Пример

<?php
error_reporting(E_ALL);
ini_set('display_errors', '0');
ini_set('log_errors', '1');

require 'vendor/autoload.php';

set_error_handler(function($severity, $message, $file, $line) {
    throw new ErrorException($message, 0, $severity, $file, $line);
});

register_shutdown_function(function() {
    $error = error_get_last();
    if ($error && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
        // Логирование фатальной ошибки
        file_put_contents('error.log', date('Y-m-d H:i:s') . ' ' . $error['message'] . PHP_EOL, FILE_APPEND);
        http_response_code(500);
        echo 'Внутренняя ошибка сервера';
    }
});

// Дальнейшая обработка запроса
?>
При возникновении E_ERROR в лог записывается сообщение, пользователь видит 500.

Пример 3: Интеграция с .htaccess для URL rewriting

Пример

# .htaccess в корне (при Apache)
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]

После этого все запросы, не ведущие к существующим файлам или директориям, направляются в index.php.

Пример: запрос /any/page → index.php обрабатывает маршрут 'any/page'.

Пример 4: Использование PSR-7 Request и Response

Пример

<?php
require 'vendor/autoload.php';

use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;

$request = Zend\Diactoros\ServerRequestFactory::fromGlobals();
$response = new Zend\Diactoros\Response();

$path = $request->getUri()->getPath();

if ($path === '/hello') {
    $response->getBody()->write('Привет, PSR-7!');
} else {
    $response = $response->withStatus(404);
    $response->getBody()->write('Не найдено');
}

// Отправка заголовков
foreach ($response->getHeaders() as $name => $values) {
    foreach ($values as $value) {
        header("$name: $value", false);
    }
}
http_response_code($response->getStatusCode());
echo $response->getBody();
?>
При GET /hello: статус 200, тело "Привет, PSR-7!"
При GET /other: статус 404, тело "Не найдено"

Пример 5: Микро-фреймворк с собственным index.php

Пример

<?php
// index.php
require 'vendor/autoload.php';

$app = new \Slim\App();

$app->get('/', function ($request, $response) {
    return $response->write('Главная');
});

$app->get('/hello/{name}', function ($request, $response, $args) {
    return $response->write('Hello, ' . $args['name']);
});

$app->run();
?>
При запросе /hello/World: "Hello, World"

Файл index.php - comments

En
Index php file (php)