php parse_url reverse - проанализированный URL
Есть ли способ отменить URL от проанализированного URL?
$url = 'http://www.domain.com/dir/index.php?query=blabla#more_bla';
$parse = parse_url($url);
print_r($parse);
/*
array(
'scheme'=>'http://',
etc....
)
*/
$revere = reverse_url($parse); // probably does not exist but u get the point
echo $reverse;
//outputs:// "http://www.domain.com/dir/index.php?query=blabla#more_bla"
Или, если есть способ проверить URL, который пропускает часть рекомендованных URL, например,
www.mydomain.com
mydomain.com
все должны вернуться http://www.mydomain.com
или с правильным поддоменом
5 ответов
Вы должны быть в состоянии сделать
http_build_url($parse)
ПРИМЕЧАНИЕ: http_build_url доступен только при установке pecl_http.
Согласно документам, он разработан специально для обработки выходных данных parse_url
, Обе функции обрабатывают якоря, параметры запроса и т. Д., Поэтому нет никаких "других свойств, не упомянутых в $url".
Добавить http://
если он отсутствует, используйте базовую проверку перед его разбором:
if (strpos($url, "http://") != 0)
$url = "http://$url";
Вот две функции, которые я использую для декомпозиции и перестроения URL:
function http_parse_query($query) {
$parameters = array();
$queryParts = explode('&', $query);
foreach ($queryParts as $queryPart) {
$keyValue = explode('=', $queryPart, 2);
$parameters[$keyValue[0]] = $keyValue[1];
}
return $parameters;
}
function build_url(array $parts) {
return (isset($parts['scheme']) ? "{$parts['scheme']}:" : '') .
((isset($parts['user']) || isset($parts['host'])) ? '//' : '') .
(isset($parts['user']) ? "{$parts['user']}" : '') .
(isset($parts['pass']) ? ":{$parts['pass']}" : '') .
(isset($parts['user']) ? '@' : '') .
(isset($parts['host']) ? "{$parts['host']}" : '') .
(isset($parts['port']) ? ":{$parts['port']}" : '') .
(isset($parts['path']) ? "{$parts['path']}" : '') .
(isset($parts['query']) ? "?{$parts['query']}" : '') .
(isset($parts['fragment']) ? "#{$parts['fragment']}" : '');
}
// Example
$parts = parse_url($url);
if (isset($parts['query'])) {
$parameters = http_parse_query($parts['query']);
foreach ($parameters as $key => $value) {
$parameters[$key] = $value; // do stuff with $value
}
$parts['query'] = http_build_query($parameters);
}
$url = build_url($parts);
Эта функция должна сделать свое дело:
/**
* @param array $parsed
* @return string
*/
function unparse_url(array $parsed) {
$get = function ($key) use ($parsed) {
return isset($parsed[$key]) ? $parsed[$key] : null;
};
$pass = $get('pass');
$user = $get('user');
$userinfo = $pass !== null ? "$user:$pass" : $user;
$port = $get('port');
$scheme = $get('scheme');
$query = $get('query');
$fragment = $get('fragment');
$authority =
($userinfo !== null ? "$userinfo@" : '') .
$get('host') .
($port ? ":$port" : '');
return
(strlen($scheme) ? "$scheme:" : '') .
(strlen($authority) ? "//$authority" : '') .
$get('path') .
(strlen($query) ? "?$query" : '') .
(strlen($fragment) ? "#$fragment" : '');
}
Вот короткий тест для этого:
function unparse_url_test() {
foreach ([
'',
'foo',
'http://www.google.com/',
'http://u:p@foo:1/path/path?q#frag',
'http://u:p@foo:1/path/path?#',
'ssh://root@host',
'://:@:1/?#',
'http://:@foo:1/path/path?#',
'http://@foo:1/path/path?#',
] as $url) {
$parsed1 = parse_url($url);
$parsed2 = parse_url(unparse_url($parsed1));
if ($parsed1 !== $parsed2) {
print var_export($parsed1, true) . "\n!==\n" . var_export($parsed2, true) . "\n\n";
}
}
}
unparse_url_test();
Этот ответ является приложением к принятому ответу @BradMace. Первоначально я добавил это как комментарий, но он предложил добавить это как отдельный ответ, так что вот он.
Оригинальный ответ для использования http_build_url($parse)
предоставленный pecl_http
будет работать для версии расширения 1.x
- версии 2.x
и позже являются объектно-ориентированными, и синтаксис изменен.
В более новой версии (проверено на pecl_http v.3.2.3
) реализация должна быть:
$httpUrl = new \http\Url($parsed);
$url = $httpUrl->toString();
Десять лет спустя, используя метод десятилетней давности:)
Учитывая, что у вас всегда будет схема и хост. Необязательно, смещения пути, запроса и фрагмента:
$a = parse_url('https://example.com/whatever-season/?drink=water&sleep=better');
Вернитесь к классному sprintf:
function buildUrl(array $a){
return sprintf('%s://%s%s%s%s',
$a['scheme'], $a['host'], $a['path'] ?? '',
$a['query'] ? '?' . $a['query'] : '',
$a['fragment'] ? '#' . $a['fragment'] : '');
}
Где смещение пути управляется оператором объединения null (PHP 7+).
Еще одна реализация:
function build_url(array $elements) {
$e = $elements;
return
(isset($e['host']) ? (
(isset($e['scheme']) ? "$e[scheme]://" : '//') .
(isset($e['user']) ? $e['user'] . (isset($e['pass']) ? ":$e[pass]" : '') . '@' : '') .
$e['host'] .
(isset($e['port']) ? ":$e[port]" : '')
) : '') .
(isset($e['path']) ? $e['path'] : '/') .
(isset($e['query']) ? '?' . (is_array($e['query']) ? http_build_query($e['query'], '', '&') : $e['query']) : '') .
(isset($e['fragment']) ? "#$e[fragment]" : '')
;
}
Результаты должны быть:
{
"host": "example.com"
}
/* //example.com/ */
{
"scheme": "https",
"host": "example.com"
}
/* https://example.com/ */
{
"scheme": "http",
"host": "example.com",
"port": 8080,
"path": "/x/y/z"
}
/* http://example.com:8080/x/y/z */
{
"scheme": "http",
"host": "example.com",
"port": 8080,
"user": "anonymous",
"query": "a=b&c=d",
"fragment": "xyz"
}
/* http://anonymous@example.com:8080/?a=b&c=d#xyz */
{
"scheme": "http",
"host": "example.com",
"user": "root",
"pass": "stupid",
"path": "/x/y/z",
"query": {
"a": "b",
"c": "d"
}
}
/* http://root:stupid@example.com/x/y/z?a=b&c=d */
{
"path": "/x/y/z",
"query": "a=b&c=d"
}
/* /x/y/z?a=b&c=d */
Получить последнюю строку из URL, например: http://example.com/controllername/functionname и необходимо получить имя функции
$ referer = explode ('/', strrev ($ _ SERVER ['HTTP_REFERER']));
$ lastString = strrev ($ referer [0]);