PHP веб-разработка: примеры и практические инструкции

Раздел: Веб-разработка -> Примеры веб-разработки

Основные подходы к созданию PHP сайта

В этом разделе рассмотрены практические варианты построения веб-сайта на PHP: от простого файлового подхода до структурированных решений с базами данных и шаблонизаторами. Каждый вариант сопровождается вопросом, на который он отвечает, а также описанием целей использования.

Как создать динамический сайт с роутингом и подключением к MySQL?

Основное решение - процедурный PHP с единой точкой входа (front controller). Такой подход подходит для небольших проектов, где нужно быстро развернуть сайт с несколькими страницами и базой данных.


<?php
// index.php - единая точка входа
$uri = $_SERVER['REQUEST_URI'];
$uri = parse_url($uri, PHP_URL_PATH);

switch ($uri) {
    case '/':
        require 'home.php';
        break;
    case '/about':
        require 'about.php';
        break;
    case '/contact':
        require 'contact.php';
        break;
    default:
        http_response_code(404);
        require '404.php';
        break;
}
?>

Подключение к базе данных выполняется с помощью PDO:


<?php
$host = 'localhost';
$db   = 'mysite';
$user = 'root';
$pass = '';
$charset = 'utf8mb4';

$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
];
try {
    $pdo = new PDO($dsn, $user, $pass, $options);
} catch (\PDOException $e) {
    die('Ошибка подключения: ' . $e->getMessage());
}
?>

В каждом файле-обработчике можно использовать переменную $pdo для запросов. Цель данного решения - минимальная настройка и быстрый старт, но при росте проекта управление становится сложным.

Как сделать статический сайт с переиспользуемыми блоками через include?

Подходит для сайтов-визиток без динамического контента. Все страницы - это HTML с вставками PHP для header/footer.


<!DOCTYPE html>
<html>
<head>
    <title>Главная</title>
</head>
<body>
    <?php include 'header.php'; ?>
    <h1>Добро пожаловать</h1>
    <p>Это статический сайт на PHP.</p>
    <?php include 'footer.php'; ?>
</body>
</html>

Проблема: при изменении структуры нужно редактировать каждую страницу. Решение - использовать единый шаблон с переменными содержимого.

Типичная ошибка - неправильные пути при подключении файлов (использовать __DIR__ или задать корневую константу).

Как организовать сайт с шаблонизатором Twig?

Вариант с Twig отделяет логику от представления. Устанавливается через Composer.


composer require twig/twig

Создание шаблона templates/index.html.twig:


<!DOCTYPE html>
<html>
<head>
    <title>{{ title }}</title>
</head>
<body>
    <h1>{{ heading }}</h1>
    <p>{{ content }}</p>
</body>
</html>

PHP код для рендеринга:


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

$loader = new \Twig\Loader\FilesystemLoader('templates');
$twig = new \Twig\Environment($loader);

echo $twig->render('index.html.twig', [
    'title'   => 'Мой сайт',
    'heading' => 'Привет!',
    'content' => 'Это контент, переданный из PHP.',
]);
?>

Цель использования - упрощение поддержки HTML и возможность наследования шаблонов.

Ошибка: отсутствие расширения mbstring может вызвать проблемы с кодировкой. Рекомендуется проверять настройки PHP.

Как написать самописный MVC для учебного проекта?

Реализация собственного MVC помогает понять принципы фреймворков. Пример структуры:


app/
  controllers/
    HomeController.php
  models/
    User.php
  views/
    home.php
public/
  index.php

Файл public/index.php - точка входа с роутингом на контроллеры:


<?php
$controllerName = $_GET['controller'] ?? 'home';
$actionName = $_GET['action'] ?? 'index';

$controllerClass = ucfirst($controllerName) . 'Controller';
if (class_exists($controllerClass)) {
    $controller = new $controllerClass();
    if (method_exists($controller, $actionName)) {
        $controller->$actionName();
    } else {
        http_response_code(404);
        echo 'Action not found';
    }
} else {
    http_response_code(404);
    echo 'Controller not found';
}
?>

Контроллер HomeController:


<?php
class HomeController {
    public function index() {
        $data = ['title' => 'Главная'];
        include '../app/views/home.php';
    }
}
?>

Подходит для обучения и небольших проектов без внешних зависимостей.

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

Общие проблемы и их решения
  • Ошибки подключения к MySQL: проверьте имя базы, пользователя и пароль. Используйте try-catch с PDO.
  • Безопасность: всегда экранируйте данные через подготовленные запросы (PDO или MySQLi).
  • Настройка веб-сервера: для ЧПУ используйте .htaccess с RewriteEngine On.
  • Кэширование: для Twig включите кэш в production для ускорения.

Расширенные примеры PHP кода

1. Конфигурация .htaccess для ЧПУ

Позволяет маршрутизировать все запросы через index.php без указания имени файла в URL.

Пример

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]

Результат: URL /about обрабатывается index.php с параметром url=about.

$_GET['url'] = 'about'

2. Безопасный класс для работы с БД (PDO обёртка)

Пример класса Database с методом query и prepared statements. Защита от SQL-инъекций.

Пример

<?php
class Database {
    private $pdo;

    public function __construct($config) {
        $dsn = "mysql:host={$config['host']};dbname={$config['db']};charset={$config['charset']}";
        $this->pdo = new PDO($dsn, $config['user'], $config['pass'], [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]);
    }

    public function query($sql, $params = []) {
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute($params);
        return $stmt->fetchAll();
    }
}

$config = [
    'host' => 'localhost',
    'db' => 'test',
    'user' => 'root',
    'pass' => '',
    'charset' => 'utf8mb4',
];
$db = new Database($config);
$users = $db->query('SELECT * FROM users WHERE status = ?', ['active']);
print_r($users);
?>
Array
(
    [0] => Array
        (
            [id] => 1
            [name] => Иван
            [status] => active
        )
)

3. Простой REST API на PHP (GET/POST)

Реализация базового API для работы с ресурсом 'tasks'. Используется JSON.

Пример

<?php
header('Content-Type: application/json');
$method = $_SERVER['REQUEST_METHOD'];

switch ($method) {
    case 'GET':
        $tasks = [
            ['id' => 1, 'title' => 'Купить молоко'],
            ['id' => 2, 'title' => 'Позвонить другу'],
        ];
        echo json_encode($tasks);
        break;
    case 'POST':
        $input = json_decode(file_get_contents('php://input'), true);
        $newTask = [
            'id' => 3,
            'title' => $input['title'] ?? 'Новая задача',
        ];
        echo json_encode($newTask);
        break;
    default:
        http_response_code(405);
        echo json_encode(['error' => 'Method not allowed']);
}
?>

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

[{"id":1,"title":"Купить молоко"},{"id":2,"title":"Позвонить другу"}]

4. Авторизация через сессии и пароль (bcrypt)

Хеширование пароля и проверка при входе. Пример использует password_hash и password_verify.

Пример

<?php
session_start();

// Регистрация
$password = 'secret';
$hash = password_hash($password, PASSWORD_BCRYPT);
// сохраняем $hash в базу

// Вход
$inputPassword = 'secret';
if (password_verify($inputPassword, $hash)) {
    $_SESSION['user_id'] = 1;
    echo 'Вход выполнен';
} else {
    echo 'Неверный пароль';
}
?>

Результат успешного входа:

Вход выполнен
- Php сайт пример (пример сайта на php)

Пример сайта на PHP - comments

En
Php сайт пример (php)