Управление URL-адресами на языке PHP

Раздел: Взаимодействие с HTTP -> Работа с URL

Основные методы работы с URL в PHP

Наиболее эффективный способ разбора и сборки URL - использование встроенных функций parse_url(), parse_str() и http_build_query(). Они обрабатывают все стандартные части адреса, включая схему, хост, порт, путь, параметры и фрагмент.

Как разобрать URL на составные части и извлечь параметры запроса?

Функция parse_url() возвращает ассоциативный массив со всеми компонентами. Для получения строки запроса и её преобразования в массив используется parse_str().


$url = 'https://user:pass@example.com:8080/path/to/page?name=John&age=30#section';
$parts = parse_url($url);
print_r($parts);

parse_str($parts['query'] ?? '', $query);
print_r($query);

Php проверить ссылку (проверить ссылку в php)

Array
(
    [scheme] => https
    [host] => example.com
    [port] => 8080
    [user] => user
    [pass] => pass
    [path] => /path/to/page
    [query] => name=John&age=30
    [fragment] => section
)
Array
(
    [name] => John
    [age] => 30
)

Id ссылки php (идентификатор ссылки в php)

Типичные ошибки:

  • Попытка извлечь query без проверки на существование - если URL не содержит строки запроса, ключ 'query' отсутствует. Всегда используйте оператор ?? или isset().
  • Игнорирование кодировки: parse_str() автоматически декодирует параметры, но если данные передавались с двойным кодированием, результат может быть неверным.
  • Неверное использование parse_url() с относительными URL - для относительных адресов функция всё равно корректно выделит путь и query, но компоненты host, scheme будут отсутствовать.

Когда может потребоваться разбор URL без использования специальных функций?

Если нужно обработать URL, не соответствующий стандарту (например, с нестандартными символами) или когда требуется полный контроль над процессом, можно разобрать строку вручную с помощью explode() и substr().


$url = 'https://example.com/path?q=test#frag';

// Разделение на схему и остальное
$schemeEnd = strpos($url, '://');
$scheme = substr($url, 0, $schemeEnd);
$rest = substr($url, $schemeEnd + 3);

// Извлечение хоста и пути
$hostEnd = strpos($rest, '/');
$host = substr($rest, 0, $hostEnd);
$pathAndQuery = substr($rest, $hostEnd);

echo "Схема: $scheme\nХост: $host\nПуть+query: $pathAndQuery";

активная ссылка php (создание активной ссылки в php)

Схема: https
Хост: example.com
Путь+query: /path?q=test#frag

Php ссылки (работа с url и ссылками в php)

Такой подход не обрабатывает сложные случаи (порт, авторизация, множественные ?). Для production лучше использовать parse_url(). Ручной разбор оправдан только при обучении или для очень специфических форматов.

Как извлечь домен или путь с помощью регулярных выражений?

Регулярные выражения позволяют гибко извлекать части URL, но код становится менее читаемым и может содержать ошибки при обработке граничных случаев.


$url = 'http://www.example.com:8080/page?id=1';
preg_match('#^([a-z]+)://([^/:]+)(:\d+)?(/[^?#]*)#i', $url, $matches);
print_r($matches);

Php адрес страницы (адрес страницы в php)

Array
(
    [0] => http://www.example.com:8080/page
    [1] => http
    [2] => www.example.com
    [3] => :8080
    [4] => /page
)

Php uri (получение uri в php)

Регулярные выражения сложно поддерживать, они не покрывают все RFC-правила URL. Рекомендуется использовать parse_url(), а не писать собственные шаблоны.

Как создать строку запроса из массива параметров?

Функция http_build_query() принимает ассоциативный массив и возвращает URL-кодированную строку. Можно указать числовой индекс, разделитель и другие параметры.


$params = ['name' => 'Иван', 'age' => 25, 'city' => 'Москва'];
$query = http_build_query($params, '', '&');
echo $query;

Php page url (url текущей страницы в php)

name=%D0%98%D0%B2%D0%B0%D0%BD&age=25&city=%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B0

По умолчанию http_build_query() использует & в качестве разделителя (с учётом HTML-сущностей), но можно задать любой. Ошибка - забыть закодировать спецсимволы, но функция делает это автоматически.

Почему важно кодировать спецсимволы в URL и как это сделать?

Для кодирования отдельных частей URL применяются urlencode() (для query string) и rawurlencode() (для пути, соответствует RFC 3986). Декодирование выполняют urldecode() и rawurldecode().


$str = 'цена=100 & товар';
echo urlencode($str) . "\n";
echo rawurlencode($str);
%D1%86%D0%B5%D0%BD%D0%B0%3D100+%26+%D1%82%D0%BE%D0%B2%D0%B0%D1%80
%D1%86%D0%B5%D0%BD%D0%B0%3D100%20%26%20%D1%82%D0%BE%D0%B2%D0%B0%D1%80

Главная ошибка - применение urlencode() ко всему URL целиком, а не к его отдельным частям, что приводит к неправильному кодированию символов :// и ?. Также путают urlencode() и rawurlencode(): первый превращает пробел в +, второй - в %20.

Как убедиться, что строка является корректным URL?

Фильтр FILTER_VALIDATE_URL из filter_var() проверяет URL на соответствие стандарту. Возвращает сам URL в случае успеха или false.


$urls = [
    'https://example.com',
    'ftp://user@host',
    'not a url',
    '//example.com/path'
];

foreach ($urls as $url) {
    echo filter_var($url, FILTER_VALIDATE_URL) ? "Валидный: $url" : "Невалидный: $url";
    echo "\n";
}
Валидный: https://example.com
Валидный: ftp://user@host
Невалидный: not a url
Невалидный: //example.com/path

FILTER_VALIDATE_URL считает URL без схемы невалидным, но протоколо-относительные ссылки (//example.com) часто встречаются на практике. Функция также не проверяет доступность хоста. Для более строгой проверки можно дополнительно разбирать URL через parse_url().

Как выполнить редирект на другой URL?

Перенаправление осуществляется отправкой HTTP-заголовка Location с помощью функции header(). Перед вызовом не должно быть вывода в браузер (даже пробелов). После заголовка обязательно вызывается exit или die.


$target = 'https://new-site.com/page';
header('Location: ' . $target);
exit;

Ошибка - попытка редиректа после вывода текста (например, после echo). Это вызывает предупреждение PHP и редирект может не сработать. Всегда проверяйте наличие вывода перед header(). Также не забудьте закодировать URL, если он содержит недопустимые символы.

Расширенные примеры обработки URL

Объединение относительного URL с базовым

Часто требуется преобразовать относительный адрес в абсолютный, используя базовый URL. Реализация учитывает все компоненты.

Пример

function resolveUrl($base, $relative) {
    $baseParts = parse_url($base);
    $relativeParts = parse_url($relative);
    
    if (isset($relativeParts['scheme'])) {
        return $relative;
    }
    
    $result = $baseParts['scheme'] . '://' . $baseParts['host'];
    if (isset($baseParts['port'])) {
        $result .= ':' . $baseParts['port'];
    }
    
    if ($relative[0] === '/') {
        $result .= $relative;
    } else {
        $basePath = dirname($baseParts['path'] ?? '/');
        if ($basePath === '\\') $basePath = '/';
        $result .= $basePath . '/' . $relative;
    }
    
    if (isset($relativeParts['query'])) {
        $result .= '?' . $relativeParts['query'];
    }
    if (isset($relativeParts['fragment'])) {
        $result .= '#' . $relativeParts['fragment'];
    }
    
    return $result;
}

echo resolveUrl('https://example.com/dir/page.php?x=1', 'sub/file.html#top');
echo "\n";
echo resolveUrl('https://example.com/dir/page.php', '/new/path');
echo "\n";
echo resolveUrl('https://example.com/dir/page.php', '//other.com/path');
https://example.com/dir/sub/file.html#top
https://example.com/new/path
https://other.com/path

Парсинг строки запроса с поддержкой множественных значений

Стандартный parse_str() корректно обрабатывает массивы параметров, но если нужно сохранить порядок или обработать повторяющиеся ключи, можно использовать пользовательскую функцию.

Пример

function parseQueryCustom($queryString) {
    $result = [];
    foreach (explode('&', $queryString) as $pair) {
        $parts = explode('=', $pair, 2);
        $key = urldecode($parts[0]);
        $value = isset($parts[1]) ? urldecode($parts[1]) : '';
        if (isset($result[$key])) {
            $result[$key] = is_array($result[$key]) ? $result[$key] : [$result[$key]];
            $result[$key][] = $value;
        } else {
            $result[$key] = $value;
        }
    }
    return $result;
}

$query = 'key1=a&key2=b&key1=c';
print_r(parseQueryCustom($query));
Array
(
    [key1] => Array
        (
            [0] => a
            [1] => c
        )
    [key2] => b
)

Кодирование и декодирование с учётом разных схем

При работе с путями URL важно использовать rawurlencode(), чтобы пробелы кодировались как %20, а не +. Пример создания полного URL из частей.

Пример

function buildUrl($scheme, $host, $port = null, $path = '', $query = [], $fragment = '') {
    $url = $scheme . '://' . $host;
    if ($port) $url .= ':' . $port;
    $url .= '/' . ltrim(rawurlencode($path), '/');
    if ($query) $url .= '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986);
    if ($fragment) $url .= '#' . rawurlencode($fragment);
    return $url;
}

echo buildUrl('https', 'example.com', 8080, 'путь/к странице', ['ключ' => 'значение'], 'якорь');
https://example.com:8080/%D0%BF%D1%83%D1%82%D1%8C/%D0%BA%20%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B5?%D0%BA%D0%BB%D1%8E%D1%87=%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B5#%D1%8F%D0%BA%D0%BE%D1%80%D1%8C

Проверка доступности URL с помощью cURL

Хотя тема статьи не про cURL, в разделе "Взаимодействие с HTTP" уместно показать, как убедиться, что URL действительно отвечает (например, код 200).

Пример

function urlExists($url) {
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_NOBODY => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 10
    ]);
    curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    return $httpCode === 200;
}

echo urlExists('https://httpstat.us/200') ? 'Существует' : 'Не найдено';
echo "\n";
echo urlExists('https://httpstat.us/404') ? 'Существует' : 'Не найдено';
Существует
Не найдено

Безопасное получение содержимого удалённого URL с проверкой ошибок

При загрузке контента по URL нужно обрабатывать ошибки соединения, таймауты и некорректные ответы. Пример с file_get_contents() и контекстом.

Пример

function fetchUrl($url) {
    $options = [
        'http' => [
            'method' => 'GET',
            'timeout' => 5,
            'ignore_errors' => true
        ]
    ];
    $context = stream_context_create($options);
    $result = @file_get_contents($url, false, $context);
    if ($result === false) {
        $error = error_get_last();
        return "Ошибка: " . ($error['message'] ?? 'Неизвестная ошибка');
    }
    return $result;
}

echo fetchUrl('https://example.com');

Ошибки: file_get_contents() не поддерживает сложные сценарии (COOKIE, перенаправления, работа с SSL-сертификатами). Для серьёзных задач используйте cURL или библиотеку Guzzle.

Работа с URL и ссылками в PHP - comments

En
Php ссылки (php)