Разбор URL: методы, примеры и типичные ошибки
Веб-приложения часто работают с URL: их необходимо анализировать, извлекать параметры, проверять корректность. В PHP существуют встроенные функции для парсинга URL, среди которых основная - parse_url.
Основные способы парсинга URL в PHP
Как разобрать URL на составные части в PHP?
Функция parse_url принимает строку URL и возвращает ассоциативный массив с ключами: scheme, host, port, user, pass, path, query, fragment. Если компонент отсутствует, он не включается в результат.
$url = 'https://user:pass@example.com:8080/path/to/page?name=value&key=val#section';
$parts = parse_url($url);
print_r($parts);Php создание ссылки (создание ссылки в php)
Array
(
[scheme] => https
[host] => example.com
[port] => 8080
[user] => user
[pass] => pass
[path] => /path/to/page
[query] => name=value&key=val
[fragment] => section
)Js php url (javascript и php url)
Для извлечения query string удобно использовать parse_str.
Типичные ошибки:
- Если URL не содержит схему (например, только домен), parse_url может интерпретировать host как path. Решение: добавлять фиктивную схему или использовать регулярные выражения.
- Функция не проверяет валидность URL - она просто разбивает строку.
- Кириллические символы в URL должны быть закодированы (rawurlencode).
Как извлечь параметры запроса из URL?
Для преобразования строки запроса в ассоциативный массив используется parse_str.
$query = 'name=Иван&age=25&city=Москва';
parse_str($query, $params);
print_r($params);
Php url (url в php)
Array
(
[name] => Иван
[age] => 25
[city] => Москва
)Php url query (url-запрос (query string) в php)
Важно: parse_str автоматически декодирует URL-кодировку.
Проблемы и ошибки:
- Если в строке запроса встречаются повторяющиеся параметры, последнее значение перезаписывает предыдущее. Для массивов нужно использовать синтаксис a[]=1&a[]=2.
- parse_str может быть небезопасна, если передавать пользовательский query string без фильтрации - возможно загрязнение глобальных переменных (если используется без второго аргумента).
Как получить все части URL и параметры запроса одновременно?
Комбинация parse_url и parse_str дает полный контроль.
$url = 'http://example.com/page?foo=bar&baz=qux';
$parts = parse_url($url);
parse_str($parts['query'] ?? '', $query);
$parts['query_params'] = $query;
print_r($parts);Php base url (базовый url в php)
Array
(
[scheme] => http
[host] => example.com
[path] => /page
[query] => foo=bar&baz=qux
[query_params] => Array
(
[foo] => bar
[baz] => qux
)
)Include php url (включение url через include в php)
Можно ли разобрать URL без встроенных функций?
Ручной разбор с помощью explode, strpos и substr возможен, но крайне не рекомендуется из-за множества подводных камней (разные форматы, порты, IPv6 и т.д.). Однако для простых фиксированных URL можно применять.
$url = 'https://example.com/path?q=1';
$parts = [];
$parts['scheme'] = substr($url, 0, strpos($url, '://'));
$rest = substr($url, strpos($url, '://') + 3);
$parts['host'] = substr($rest, 0, strpos($rest, '/'));
$parts['path'] = substr($rest, strpos($rest, '/'));
echo 'Схема: ' . $parts['scheme'] . ', хост: ' . $parts['host'] . ', путь: ' . $parts['path'];Mobile php url (мобильный url в php)
Схема: https, хост: example.com, путь: /path?q=1
Php параметр url (параметры url в php)
Такой подход не учитывает query и fragment.
Недостатки ручного разбора:
- Сложность обработки порта, авторизации, фрагмента.
- Ошибки при отсутствии пути.
- IPv6 адреса требуют дополнительных проверок.
Как проверить корректность URL перед разбором?
Фильтр FILTER_VALIDATE_URL проверяет, является ли строка валидным URL по стандарту.
$url1 = 'https://example.com';
$url2 = 'not a url';
var_dump(filter_var($url1, FILTER_VALIDATE_URL));
var_dump(filter_var($url2, FILTER_VALIDATE_URL));Php текущая url (текущая url в php)
string(19) "https://example.com" bool(false)
Php строка url (строка url в php)
Только после проверки можно безопасно применять parse_url.
Как собрать URL обратно из разобранных компонентов?
Имея массив от parse_url, можно восстановить URL с помощью sprintf или склеивания строк.
$parts = [
'scheme' => 'https',
'host' => 'example.com',
'port' => 8080,
'path' => '/api/v1',
'query' => 'key=val',
'fragment' => 'section'
];
$url = $parts['scheme'] . '://' . $parts['host'];
if (isset($parts['port'])) $url .= ':' . $parts['port'];
$url .= $parts['path'] ?? '';
if (isset($parts['query'])) $url .= '?' . $parts['query'];
if (isset($parts['fragment'])) $url .= '#' . $parts['fragment'];
echo $url;Php parse url (парсинг url в php)
https://example.com:8080/api/v1?key=val#section
Расширенные примеры парсинга и сборки URL
Пример 1. Разбор URL с авторизацией, портом и фрагментом
URL может содержать имя пользователя и пароль, порт, путь, query и фрагмент.
$url = 'ftp://user:password@ftp.example.com:2121/docs/file.txt?mode=ascii#download';
$parsed = parse_url($url);
print_r($parsed);
Array
(
[scheme] => ftp
[host] => ftp.example.com
[port] => 2121
[user] => user
[pass] => password
[path] => /docs/file.txt
[query] => mode=ascii
[fragment] => download
)
Функция корректно выделяет все компоненты. Для дальнейшей работы с query используется parse_str.
Пример 2. Разбор относительного URL (без схемы)
Если URL не содержит схему, parse_url может некорректно определить host. Например, для URL //example.com/path (протоколонезависимый) или /path?q=1 (относительный без домена).
$urls = [
'//example.com/path',
'/path/to/resource',
'?query=string',
'#fragment'
];
foreach ($urls as $url) {
$parts = parse_url($url);
if (!isset($parts['scheme']) && strpos($url, '//') === 0) {
// Протоколонезависимый - можно добавить схему по умолчанию
$fullUrl = 'https:' . $url;
$parts = parse_url($fullUrl);
} elseif (!isset($parts['host']) && !isset($parts['scheme'])) {
// Относительный путь - восстановить по базовому URL
$baseUrl = 'https://example.com';
$fullUrl = $baseUrl . $url; // упрощенно
$parts = parse_url($fullUrl);
}
print_r($parts);
}
Array ( [scheme] => https [host] => example.com [path] => /path ) Array ( [scheme] => https [host] => example.com [path] => /path/to/resource ) Array ( [scheme] => https [host] => example.com [path] => /page?query=string ) Array ( [scheme] => https [host] => example.com [path] => /page#fragment )
Для корректного восстановления относительных URL рекомендуется использовать библиотеку PSR-7 или строить на основе контекста.
Пример 3. Разбор query string c массивами
Параметры запроса могут иметь синтаксис массивов: a[]=1&a[]=2&b[key]=value. Функция parse_str обрабатывает их.
$query = 'filter[]=price&filter[]=brand&sort[field]=name&sort[order]=asc';
parse_str($query, $result);
print_r($result);
Array
(
[filter] => Array
(
[0] => price
[1] => brand
)
[sort] => Array
(
[field] => name
[order] => asc
)
)
Это удобно для обработки данных из форм или HTTP-запросов.
Пример 4. Сборка URL с использованием http_build_query
Функция http_build_query формирует строку запроса из массива, автоматически кодируя ключи и значения.
$params = [
'name' => 'Алексей',
'age' => 30,
'tags' => ['php', 'url', 'parsing']
];
$queryString = http_build_query($params, '', '&', PHP_QUERY_RFC3986);
$url = 'https://example.com/search?' . $queryString;
echo $url;
https://example.com/search?name=%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B5%D0%B9&age=30&tags%5B0%5D=php&tags%5B1%5D=url&tags%5B2%5D=parsing
Параметр PHP_QUERY_RFC3986 обеспечивает кодирование в соответствии с RFC 3986.
Пример 5. Валидация, разбор и обработка ошибок
Перед разбором стоит проверить URL с помощью filter_var, а затем обработать отсутствующие компоненты.
function parseUrlSafe(string $url): ?array {
if (!filter_var($url, FILTER_VALIDATE_URL)) {
return null;
}
$parts = parse_url($url);
// Дополнительная обработка: преобразование query в массив
if (isset($parts['query'])) {
parse_str($parts['query'], $parts['query_params']);
} else {
$parts['query_params'] = [];
}
return $parts;
}
$testUrls = [
'https://example.com/test?foo=bar',
'invalid-url',
'ftp://user@host:21/path'
];
foreach ($testUrls as $u) {
$result = parseUrlSafe($u);
echo $result ? 'OK: ' . json_encode($result) : 'FAIL: ' . $u;
echo "\n";
}
OK: {"scheme":"https","host":"example.com","path":"\/test","query":"foo=bar","query_params":{"foo":"bar"}}
FAIL: invalid-url
OK: {"scheme":"ftp","host":"host","port":21,"user":"user","path":"\/path","query_params":[]}
Функция возвращает null для невалидного URL, что позволяет избежать ошибок в дальнейшем коде.
Пример 6. Работа с кириллическими URL и кодированием
Если URL содержит кириллические символы, их необходимо кодировать. Функции urlencode и rawurlencode отличаются: последний кодирует пробелы как %20, а не +.
$url = 'https://example.com/путь до файла?имя=значение#якорь';
$encoded = rawurlencode($url); // кодирует весь URL (неправильно)
// Правильный подход: кодировать отдельные части
$path = '/путь до файла';
$query = 'имя=значение';
$fragment = 'якорь';
$urlEncoded = 'https://example.com' . rawurlencode($path) . '?' . rawurlencode($query) . '#' . rawurlencode($fragment);
echo $urlEncoded . "\n";
// Обратное декодирование
echo rawurldecode($urlEncoded);
https://example.com%2F%D0%BF%D1%83%D1%82%D1%8C%20%D0%B4%D0%BE%20%D1%84%D0%B0%D0%B9%D0%BB%D0%B0?%D0%B8%D0%BC%D1%8F%3D%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 https://example.com/путь до файла?имя=значение#якорь
Для разбора URL с кириллицей применяются функции rawurlencode и rawurldecode.