Разработка системы управления редиректами сайта
Система управления редиректами позволяет настраивать 301/302/307-перенаправления через интерфейс CMS без изменений в конфигурации веб-сервера. Критична при реструктуризации сайта, смене URL-структуры, удалении страниц.
Модель данных
redirects (
id, from_path, to_url,
http_code: 301 | 302 | 307,
is_active,
hits, -- количество срабатываний
last_hit_at, -- дата последнего срабатывания
created_by, created_at, note
)
Middleware для редиректов
class HandleRedirects
{
public function handle(Request $request, Closure $next): Response
{
$path = '/' . ltrim($request->path(), '/');
$redirect = Cache::remember('redirect:' . md5($path), 3600, function () use ($path) {
return Redirect::where('from_path', $path)
->where('is_active', true)
->first(['to_url', 'http_code']);
});
if ($redirect) {
Redirect::where('from_path', $path)->increment('hits');
Redirect::where('from_path', $path)->update(['last_hit_at' => now()]);
return redirect($redirect->to_url, $redirect->http_code);
}
return $next($request);
}
}
Middleware регистрируется в bootstrap/app.php в группе web с высоким приоритетом.
Импорт редиректов из CSV
При миграции сайта нужно загрузить сотни или тысячи редиректов сразу:
public function importFromCsv(UploadedFile $file): array
{
$rows = array_map('str_getcsv', file($file->getRealPath()));
$header = array_shift($rows); // первая строка — заголовки
$created = $skipped = $errors = 0;
foreach (array_chunk($rows, 500) as $chunk) {
$inserts = [];
foreach ($chunk as $row) {
$data = array_combine($header, $row);
if (empty($data['from']) || empty($data['to'])) { $errors++; continue; }
$inserts[] = [
'from_path' => '/' . ltrim($data['from'], '/'),
'to_url' => $data['to'],
'http_code' => $data['code'] ?? 301,
'is_active' => true,
'created_at' => now()
];
$created++;
}
Redirect::upsert($inserts, ['from_path'], ['to_url', 'http_code']);
}
return compact('created', 'skipped', 'errors');
}
Регулярные выражения (опционально)
Для сложных паттернов:
// Redirect с regex: /blog/2023/* → /news/*
$redirect = Redirect::where('from_path', 'LIKE', '/blog/%')
->where('is_regex', true)
->get();
foreach ($redirect as $r) {
if (preg_match($r->from_path, $path, $matches)) {
$to = preg_replace($r->from_path, $r->to_url, $path);
return redirect($to, $r->http_code);
}
}
Определение битых ссылок
Запускать периодически — проверять from_path редиректов на наличие входящих ссылок с других страниц сайта. Редиректы без входящих ссылок и без срабатываний за 6 месяцев — кандидаты на удаление.
Срок разработки: 2–3 дня для системы с импортом CSV, кешированием и интерфейсом управления.







