Это более распространено, чем вы думаете
Почти каждый фриланс-разработчик рано или поздно получает устаревший проект. Никакой документации. Никакой истории git. PHP 5.6 или 7.0. MySQL-запросы непосредственно в файлах шаблонов. Папка с названием final_FINAL_v3_use_this.
Клиент не хочет переписывать — он просто хочет, чтобы оно не ломалось. Вот как подойти к этому профессионально.
Шаг 1: Пока ничего не трогайте
Прежде чем изменить хоть один файл:
- Сделайте полное резервное копирование — файлы и базу данных. Загрузите всё через FTP. Экспортируйте базу данных с помощью
mysqldump. - Настройте копию для тестирования — клонируйте сайт на поддомен или локальное окружение. Всю работу выполняйте сначала там.
- Включите логирование ошибок — не показ, только запись в журнал. Вы хотите увидеть, что уже сломано.
// Добавьте в начало главного index.php или конфигурационного файла
ini_set('display_errors', 0);
ini_set('log_errors', 1);
ini_set('error_log', __DIR__ . '/error.log');
error_reporting(E_ALL);
Шаг 2: Составьте карту сайта
Потратьте 30–60 минут просто на понимание структуры, прежде чем писать код.
# Подсчитать файлы PHP
find . -name "*.php" | wc -l
# Найти точки входа
find . -name "index.php" | head -20
# Найти конфигурационные файлы (часто содержат учетные данные БД и настройки)
find . -name "config.php" -o -name "settings.php" -o -name "configuration.php"
# Найти недавно измененные файлы (признаки недавней работы или активного редактирования)
find . -name "*.php" -mtime -30 | sort
Ищите:
- Где устанавливается соединение с базой данных
- Есть ли фреймворк (CodeIgniter, собственный MVC, или вообще без фреймворка)
- Как выглядит маршрутизация URL (правила mod_rewrite в .htaccess?)
- Есть ли система шаблонов, или необработанный PHP в HTML
Шаг 3: Поймите базу данных
-- Список всех таблиц с количеством строк
SELECT table_name, table_rows
FROM information_schema.tables
WHERE table_schema = DATABASE()
ORDER BY table_rows DESC;
-- Найти основные таблицы (пользователи, заказы, товары и т.д.)
SHOW TABLES;
Посмотрите на самые большие таблицы — там хранятся самые важные данные. Просмотрите несколько строк, чтобы понять модель данных.
Шаг 4: Определите, что на самом деле ломается
Проверьте журнал ошибок, который вы только что включили. У большинства устаревших сайтов есть куча предупреждений — не все они важны. Приоритет:
- Фатальные ошибки — то, что ломает страницы
- Устаревшие вызовы функций — они становятся фатальными на PHP 8
- Ошибки базы данных — неудачные запросы, проблемы с подключением
# Подсчитать типы ошибок в журнале
grep "Fatal error" error.log | wc -l
grep "Deprecated" error.log | sort | uniq -c | sort -rn | head -20
grep "Warning" error.log | sort | uniq -c | sort -rn | head -20
Шаг 5: Перед изменениями создайте предохранитель
В устаревшем коде нет тестов. Это означает, что любое изменение может сломать то, чего вы не ожидали.
Минимальный предохранитель:
- Составьте список самых важных страниц/потоков (главная, вход, оформление заказа, ключевые формы)
- Задокументируйте, как выглядит «рабочее состояние» для каждого (вручную, при необходимости со скриншотами)
- После каждого изменения вручную проверьте, работает ли каждый ключевой поток
Для чего-то более сложного поможет простой скрипт дымового теста:
// smoke_test.php — запускать после каждого изменения
$pages = [
"/",
"/login",
"/products",
"/cart",
"/checkout",
];
foreach ($pages as $page) {
$url = "http://localhost" . $page;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
echo ($status === 200 ? "✓" : "✗") . " [{$status}] {$page}
";
}
Шаг 6: Исправляйте в порядке влияния
Порядок приоритетов для устаревшего PHP-сайта:
- Безопасность — SQL-инъекции, утечка учетных данных, уязвимости загрузки файлов. Не обсуждается.
- Фатальные ошибки — то, что ломается. Исправьте их сначала.
- Совместимость с PHP — если нужно обновление версии, запустите phpcs, чтобы получить список всех проблем
- Предупреждения об устаревшем — систематически очищайте их; они становятся фатальными на PHP 8
- Производительность — только после того, как предыдущее стабильно
Распространенные проблемы безопасности в устаревшем PHP
// УЯЗВИМО — SQL-инъекция
$id = $_GET['id'];
$q = mysql_query("SELECT * FROM users WHERE id = $id");
// ИСПРАВЛЕНО — параметризованный запрос
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$_GET['id']]);
// УЯЗВИМО — XSS
echo "Hello " . $_GET['name'];
// ИСПРАВЛЕНО
echo "Hello " . htmlspecialchars($_GET['name'], ENT_QUOTES, 'UTF-8');
// УЯЗВИМО — обход пути к файлу
include $_GET['page'] . '.php';
// ИСПРАВЛЕНО — белый список разрешенных страниц
$allowed = ['home', 'about', 'contact'];
$page = in_array($_GET['page'], $allowed) ? $_GET['page'] : 'home';
include $page . '.php';
Решение о переписывании
Этот вопрос возникает всегда. Мое эмпирическое правило:
Исправляйте и поддерживайте, если:
- Сайт работает и ему просто нужно пережить обновление PHP
- Бизнес-логика сложна и хорошо проверена годами работы в продакшене
- Бюджет ограничен
Переписывайте, если:
- Уязвимости безопасности фундаментальны для архитектуры (их нельзя залатать)
- Сайту нужны новые функции, которые невозможно добавить аккуратно
- Кодовая база настолько запутана, что каждое исправление ломает две другие вещи
Большинство устаревших сайтов, которые я вижу, стоят поддержки, а не переписывания. Оценка переписывания всегда в 3 раза выше, чем ожидает клиент, и это занимает 6 месяцев вместо 6 недель.
Если вы попробовали шаги выше и всё ещё не получилось (или не хотите делать это сами) — мы в DevCev Digital можем помочь вам с аудитом и поддержкой устаревшего кода.