Топ ошибок начинающих PHP разработчиков: от А до Я
PHP — один из самых популярных языков для веб-разработки, но его гибкость и низкий порог входа часто играют злую шутку с новичками. Многие начинающие разработчики допускают одни и те же ошибки, которые приводят к уязвимостям, медленной работе сайта или просто нечитаемому коду. В этой статье мы разберём топ ошибок PHP-разработчиков — от синтаксических до архитектурных — и покажем, как их исправить.
1. Ошибки безопасности: инъекции и XSS
SQL-инъекции
Самая распространённая и опасная ошибка — вставка пользовательских данных напрямую в SQL-запрос. Никогда не делайте так:
<?php
// ❌ ОПАСНО: уязвимость для SQL-инъекций
$id = $_GET['id'];
$query = "SELECT * FROM users WHERE id = $id";
$result = mysqli_query($conn, $query);
?>
Злоумышленник может передать id=1; DROP TABLE users-- и уничтожить базу данных. Всегда используйте подготовленные запросы (prepared statements):
<?php
// ✅ БЕЗОПАСНО: подготовленный запрос
$stmt = $conn->prepare("SELECT * FROM users WHERE id = ?");
$stmt->bind_param("i", $_GET['id']);
$stmt->execute();
$result = $stmt->get_result();
?>
XSS-атаки (Cross-Site Scripting)
Вывод пользовательских данных без экранирования — ещё одна классическая ошибка PHP-разработчиков:
<?php
// ❌ ОПАСНО: XSS-уязвимость
echo "Привет, " . $_GET['name'];
?>
Если пользователь передаст ?name=<script>alert('XSS')</script>, скрипт выполнится. Используйте функцию htmlspecialchars():
<?php
// ✅ БЕЗОПАСНО: экранирование HTML
echo "Привет, " . htmlspecialchars($_GET['name'], ENT_QUOTES, 'UTF-8');
?>
2. Проблемы с типами данных и сравнением
Неявное приведение типов
PHP — язык со слабой типизацией, и новички часто попадаются на неожиданном поведении:
<?php
// ❌ ОШИБКА: неявное приведение
var_dump("123abc" == 123); // true! Строка приводится к числу
var_dump(0 == "string"); // true! Строка приводится к 0
?>
Используйте строгое сравнение === вместо ==:
<?php
// ✅ ПРАВИЛЬНО: строгое сравнение
var_dump("123abc" === 123); // false
var_dump(0 === "string"); // false
?>
Путаница между empty() и isset()
Многие начинающие PHP-разработчики не понимают разницы между этими функциями:
<?php
$var = 0;
// ❌ ОШИБКА: empty() считает 0 пустым значением
if (empty($var)) {
echo "Переменная пуста"; // Выведет это сообщение!
}
// ✅ ПРАВИЛЬНО: isset() проверяет только существование
if (isset($var)) {
echo "Переменная существует и равна " . $var; // Выведет "0"
}
?>
3. Плохая практика работы с формами и данными
Игнорирование валидации на сервере
Начинающие разработчики часто полагаются только на клиентскую валидацию (JavaScript), но злоумышленник может отправить запрос напрямую на сервер. Всегда проверяйте данные на серверной стороне:
<?php
// ❌ ОШИБКА: нет серверной валидации
$email = $_POST['email'];
mail($email, "Тема", "Сообщение"); // Можно отправить письмо на любой адрес
// ✅ ПРАВИЛЬНО: проверяем email
$email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);
if ($email === false) {
die("Некорректный email");
}
mail($email, "Тема", "Сообщение");
?>
Неправильная обработка загрузки файлов
Ещё одна типичная ошибка PHP-разработчиков — сохранение файлов без проверки расширения и MIME-типа:
<?php
// ❌ ОПАСНО: можно загрузить PHP-шелл
move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/' . $_FILES['file']['name']);
// ✅ БЕЗОПАСНО: проверяем расширение
$allowed = ['jpg', 'png', 'gif'];
$ext = strtolower(pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION));
if (!in_array($ext, $allowed)) {
die("Недопустимый тип файла");
}
move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/' . uniqid() . '.' . $ext);
?>
4. Архитектурные и стилистические ошибки
Смешивание логики и представления
Классическая ошибка новичков — писать HTML прямо внутри PHP-кода. Это делает код нечитаемым и сложным в поддержке:
<?php
// ❌ ПЛОХО: смешивание логики и представления
echo "<html><body>";
$result = mysqli_query($conn, "SELECT * FROM users");
while ($row = mysqli_fetch_assoc($result)) {
echo "<p>" . $row['name'] . "</p>";
}
echo "</body></html>";
?>
Используйте разделение логики и шаблонов (например, с помощью MVC или простого include):
<?php
// ✅ ХОРОШО: логика отдельно
$users = [];
$result = mysqli_query($conn, "SELECT * FROM users");
while ($row = mysqli_fetch_assoc($result)) {
$users[] = $row;
}
include 'templates/users_list.php';
?>
Игнорирование обработки ошибок
Многие начинающие PHP-разработчики не проверяют результат выполнения функций, особенно при