PHP-коды в разработке приложений: готовые решения с примерами

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

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

Основной подход: работа с базой данных через PDO

Как безопасно подключиться к MySQL и выполнить запрос?

Самый эффективный способ в современном PHP - использовать расширение PDO с подготовленными выражениями. Это защищает от SQL-инъекций и упрощает работу с разными СУБД.


<?php
$host = 'localhost';
$db   = 'mydb';
$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,
    PDO::ATTR_EMULATE_PREPARES   => false,
];
try {
    $pdo = new PDO($dsn, $user, $pass, $options);
} catch (\PDOException $e) {
    die('Ошибка подключения: ' . $e->getMessage());
}

// Подготовленный запрос с параметрами
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email');
$stmt->execute(['email' => 'user@example.com']);
$user = $stmt->fetch();
?>

Php коды приложение (php-коды для приложений)

Типичные проблемы и их решения:

  • Ошибка подключения: проверьте правильность имени хоста, базы, пользователя и пароля. Убедитесь, что сервер MySQL запущен.
  • Не отображаются ошибки: установите режим исключений PDO::ERRMODE_EXCEPTION.
  • Проблемы с кодировкой: указывайте charset utf8mb4 в DSN и в таблицах.

Цель использования:

Данный код применяется для создания безопасного соединения с базой данных, когда требуется выполнять множество запросов с различными параметрами, избегая инъекций.

Как выполнить тот же запрос с помощью MySQLi (объектно-ориентированный стиль)?


<?php
$mysqli = new mysqli('localhost', 'root', '', 'mydb');
if ($mysqli->connect_error) {
    die('Ошибка подключения: ' . $mysqli->connect_error);
}
$stmt = $mysqli->prepare('SELECT * FROM users WHERE email = ?');
$stmt->bind_param('s', $email);
$email = 'user@example.com';
$stmt->execute();
$result = $stmt->get_result();
$user = $result->fetch_assoc();
$stmt->close();
?>

Проблемы: MySQLi поддерживает только MySQL. Легко забыть вызвать bind_param с правильными типами. Ошибки могут быть неочевидны, если не проверять возвращаемые значения.

Используется, когда проект завязан исключительно на MySQL и миграция на другую СУБД не планируется.

Как использовать ORM для работы с базой (например, Doctrine)?


<?php
// composer require doctrine/orm
use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;

$paths = [__DIR__.'/src/Entity'];
$isDevMode = true;
$dbParams = [
    'driver'   => 'pdo_mysql',
    'host'     => 'localhost',
    'dbname'   => 'mydb',
    'user'     => 'root',
    'password' => '',
];

$config = Setup::createAnnotationMetadataConfiguration($paths, $isDevMode);
$entityManager = EntityManager::create($dbParams, $config);

// Пример запроса через DQL
$query = $entityManager->createQuery('SELECT u FROM App\Entity\User u WHERE u.email = :email');
$query->setParameter('email', 'user@example.com');
$user = $query->getOneOrNullResult();
?>

Проблемы: требует настройки маппинга и автозагрузки. Высокое потребление памяти, сложная конфигурация. Для простых приложений избыточно.

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

Как обработать пользовательский ввод и сохранить в сессию?


<?php
session_start();

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['username'])) {
    $username = htmlspecialchars(trim($_POST['username']), ENT_QUOTES, 'UTF-8');
    $_SESSION['username'] = $username;
    header('Location: profile.php');
    exit;
}
?>

Проблемы: если не вызвать session_start() в начале каждого скрипта, сессия не будет доступна. Опасность XSS-атак при выводе данных без фильтрации.

Применяется для авторизации, временного хранения данных между запросами.

Расширенные примеры PHP-кодов для приложений

Ниже приведены более сложные и нестандартные примеры, которые пригодятся в реальной разработке.

1. Транзакция с PDO и обработкой ошибок

Пример

<?php
try {
    $pdo->beginTransaction();
    
    $stmt1 = $pdo->prepare('UPDATE accounts SET balance = balance - :amount WHERE id = :from');
    $stmt1->execute(['amount' => 100, 'from' => 1]);
    
    $stmt2 = $pdo->prepare('UPDATE accounts SET balance = balance + :amount WHERE id = :to');
    $stmt2->execute(['amount' => 100, 'to' => 2]);
    
    if (someCheck()) {
        throw new Exception('Условие не выполнено');
    }
    
    $pdo->commit();
} catch (Exception $e) {
    $pdo->rollBack();
    echo 'Ошибка: ' . $e->getMessage();
}
?>
При успехе вывод отсутствует, при ошибке: "Ошибка: Условие не выполнено"

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

2. Генерация безопасного пароля и его проверка

Пример

<?php
$plainPassword = 'mySecret123';
$hash = password_hash($plainPassword, PASSWORD_BCRYPT, ['cost' => 12]);
echo 'Хеш: ' . $hash . PHP_EOL;

// Проверка
if (password_verify($plainPassword, $hash)) {
    echo 'Пароль верен';
} else {
    echo 'Пароль неверен';
}
?>
Хеш: $2y$12$zL.. (случайная строка)
Пароль верен

Используется для хранения паролей: bcrypt гарантирует устойчивость к брутфорсу.

3. Простая маршрутизация (роутинг) без фреймворка

Пример

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

switch (true) {
    case $uri === '/login':
        require 'controllers/login.php';
        break;
    case $uri === '/register':
        require 'controllers/register.php';
        break;
    case preg_match('#^/user/(\d+)$#', $uri, $matches) === 1:
        $userId = (int)$matches[1];
        require 'controllers/user.php';
        break;
    default:
        http_response_code(404);
        echo 'Страница не найдена';
}
?>
При запросе /user/42 выполняется controllers/user.php с переменной $userId = 42

Подходит для небольших приложений, когда не хочется подключать фреймворк.

4. Отправка email с вложением через PHPMailer (без фреймворка)

Пример

<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHpmailer\PHPMailer\Exception;

require 'vendor/autoload.php';

$mail = new PHPMailer(true);
try {
    $mail->isSMTP();
    $mail->Host       = 'smtp.example.com';
    $mail->SMTPAuth   = true;
    $mail->Username   = 'user@example.com';
    $mail->Password   = 'secret';
    $mail->SMTPSecure = 'tls';
    $mail->Port       = 587;

    $mail->setFrom('from@example.com', 'Отправитель');
    $mail->addAddress('to@example.com', 'Получатель');
    $mail->addAttachment('document.pdf');

    $mail->isHTML(true);
    $mail->Subject = 'Тема письма';
    $mail->Body    = '<h1>Привет</h1><p>Это HTML-письмо.</p>';
    $mail->AltBody = 'Текстовая версия';

    $mail->send();
    echo 'Письмо отправлено';
} catch (Exception $e) {
    echo 'Ошибка: ' . $mail->ErrorInfo;
}
?>
При успехе: "Письмо отправлено", при ошибке: "Ошибка: ..."

Расширенный пример: отправка писем с вложениями и HTML-разметкой через SMTP.

5. Кэширование результатов запроса в файл

Пример

<?php
$cacheFile = 'cache/data.cache';
$cacheTime = 3600; // 1 час

if (file_exists($cacheFile) && (time() - filemtime($cacheFile) < $cacheTime)) {
    $data = unserialize(file_get_contents($cacheFile));
} else {
    // Долгая выборка из базы
    $stmt = $pdo->query('SELECT * FROM big_table');
    $data = $stmt->fetchAll();
    file_put_contents($cacheFile, serialize($data));
}

// Используем $data
?>
При первом запросе данные загружаются из БД и сохраняются в файл. При повторных запросах в течение часа данные берутся из кэша, что ускоряет загрузку страницы.

Подходит для данных, которые редко обновляются (списки городов, конфигурации).

PHP-коды для приложений - comments

En
Php коды приложение (php)