Получение и валидация URL из POST-запроса в PHP
Основные подходы к приёму ссылок
Наиболее эффективное решение: получение и валидация URL через filter_var
Принять ссылку из POST-запроса можно через суперглобальный массив $_POST. Однако безопасность требует проверки и очистки данных. Оптимальный способ - сочетание filter_var с флагом FILTER_VALIDATE_URL и функция экранирования htmlspecialchars для вывода.
$rawUrl = $_POST['link'] ?? '';
$validatedUrl = filter_var($rawUrl, FILTER_VALIDATE_URL);
if ($validatedUrl !== false) {
$safeUrl = htmlspecialchars($validatedUrl, ENT_QUOTES, 'UTF-8');
echo "Получен корректный URL: $safeUrl";
} else {
echo "Переданная строка не является валидным URL";
}
Php post array (массив $_post в php)
Этот блок проверяет, что в $_POST['link'] действительно содержится URL (согласно стандарту), а затем безопасно выводит его. Если проверка не пройдена, выводится сообщение об ошибке.
Типичная проблема:
Фильтр FILTER_VALIDATE_URL не пропускает многие реально работающие адреса, например, содержащие кириллицу (IDN) или localhost без точки. Решение - дополнительная кастомная проверка или использование расширения intl для декодирования IDN.
Простое присваивание без валидации
Вопрос: как принять ссылку без какой-либо проверки, если обрабатывается только внутренний трафик?
$link = $_POST['url'] ?? '';
Php параметры post (параметры post-запроса в php)
Однако это опасно: при выводе такой ссылки без экранирования возникает XSS. Если ссылка сохраняется в БД, она также должна быть экранирована при вставке.
Риски:
Вставка неэкранированного значения в HTML может привести к внедрению скриптов. Даже при внутреннем использовании стоит применить htmlspecialchars.
Разбор URL на компоненты
Вопрос: как извлечь схему, хост, путь из переданной ссылки для дальнейшего анализа?
Функция parse_url разбивает URL на ассоциативный массив.
$url = $_POST['link'];
$parts = parse_url($url);
if ($parts !== false) {
echo 'Схема: ' . ($parts['scheme'] ?? 'не указана') . "\n";
echo 'Хост: ' . ($parts['host'] ?? 'не указан') . "\n";
echo 'Путь: ' . ($parts['path'] ?? 'не указан') . "\n";
}
Php post link (работа со ссылками в post-запросе php)
Особенности:
parse_url не проверяет валидность URL как такового, только разбирает строку. Для нестандартных схем (например, ftp://) может работать некорректно.
Преобразование относительной ссылки в абсолютную
Вопрос: как дополнить относительный путь до полного URL, используя базовый адрес?
$base = 'https://example.com';
$relative = $_POST['path'];
// Используем parse_url для объединения
if (strpos($relative, '://') === false) {
$absolute = rtrim($base, '/') . '/' . ltrim($relative, '/');
} else {
$absolute = $relative;
}
echo $absolute;
Более надёжное решение - использование класса Normalizer из библиотеки или функции stream_resolve_include_path.
Проверка доступности ссылки через cURL
Вопрос: как убедиться, что переданный URL ведёт на реально существующий ресурс?
$url = filter_var($_POST['link'], FILTER_VALIDATE_URL);
if ($url !== false) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode >= 200 && $httpCode < 400) {
echo "Ссылка доступна (HTTP $httpCode)";
} else {
echo "Ссылка недоступна (HTTP $httpCode)";
}
} else {
echo "Некорректный URL";
}
Ограничения:
Запрос cURL может замедлить обработку, особенно при ожидании таймаута. Не рекомендуется выполнять такие проверки при каждом запросе. Лучше асинхронно или кешировать результаты.
Сохрание ссылки в базу данных с защитой
Вопрос: как записать принятую ссылку в MySQL, избегая SQL-инъекций?
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
$stmt = $pdo->prepare('INSERT INTO links (url) VALUES (:url)');
$stmt->execute([':url' => $validatedUrl]);
Валидация перед вставкой обязательна, а также экранирование через подготовленные запросы.
Расширенные примеры работы с ссылками в POST-запросах
// Пример 1: Декодирование IDN (интернациональных доменов)
$url = 'http://пример.рф';
$encoded = idn_to_ascii($url, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46);
echo "ASCII форма: $encoded\n";
$decoded = idn_to_utf8($encoded, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46);
echo "UTF-8 форма: $decoded\n";
ASCII форма: http://xn--e1afmkfd.xn--p1ai UTF-8 форма: http://пример.рф
// Пример 2: Извлечение домена второго уровня и TLD
$url = $_POST['site'];
$parsed = parse_url($url);
$host = $parsed['host'] ?? '';
$parts = explode('.', $host);
$domain = $parts[count($parts)-2] ?? '';
$tld = $parts[count($parts)-1] ?? '';
echo "Домен: $domain, TLD: $tld";
Домен: example, TLD: com
// Пример 3: Преобразование ссылки с параметрами в ассоциативный массив
$url = 'https://example.com/page?name=John&age=30';
$query = parse_url($url, PHP_URL_QUERY);
parse_str($query, $params);
print_r($params);
Array
(
[name] => John
[age] => 30
)
// Пример 4: Проверка на принадлежность домена к белому списку
$whitelist = ['example.com', 'mysite.org'];
$url = $_POST['link'];
$host = parse_url($url, PHP_URL_HOST);
if (in_array($host, $whitelist)) {
echo "Разрешённый домен";
} else {
echo "Домен не в белом списке";
}
Разрешённый домен
// Пример 5: Формирование короткой ссылки (внутренняя логика)
$longUrl = $_POST['long_url'];
$shortCode = substr(md5($longUrl . time()), 0, 8);
$shortUrl = "https://short.example/$shortCode";
echo "Короткая ссылка: $shortUrl";
Короткая ссылка: https://short.example/a1b2c3d4
Важно:
Во всех примерах, где данные выводятся на страницу, необходимо использовать htmlspecialchars для защиты от XSS. Также при работе с внешними URL стоит учитывать возможность перенаправлений и вредоносного контента.