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
?>
При первом запросе данные загружаются из БД и сохраняются в файл. При повторных запросах в течение часа данные берутся из кэша, что ускоряет загрузку страницы.
Подходит для данных, которые редко обновляются (списки городов, конфигурации).