parse_url

(PHP 3, PHP 4, PHP 5)

parse_url -- Parse a URL and return its components

Описание

array parse_url ( string url )

This function parses a URL and returns an associative array containing any of the various components of the URL that are present.

This function is not meant to validate the given URL, it only breaks it up into the above listed parts. Partial URLs are also accepted, parse_url() tries its best to parse them correctly.

Список параметров

url

The URL to parse

Возвращаемые значения

On seriously malformed URLs, parse_url() may return FALSE and emit a E_WARNING. Otherwise an associative array is returned, whose components may be (at least one):

  • scheme - e.g. http

  • host

  • port

  • user

  • pass

  • path

  • query - after the question mark ?

  • fragment - after the hashmark #

Примеры

Пример 1. A parse_url() example

<?php
$url
= 'http://username:password@hostname/path?arg=value#anchor';

print_r(parse_url($url));
?>

Результат выполнения данного примера:

Array
(
    [scheme] => http
    [host] => hostname
    [user] => username
    [pass] => password
    [path] => /path
    [query] => arg=value
    [fragment] => anchor
)

Примечания

Замечание: This function doesn't work with relative URLs.

Замечание: parse_url() is intended specifically for the purpose of parsing URLs and not URIs. However, to comply with PHP's backwards compatibility requirements it makes an exception for the file:// scheme where tripple slashes (file:///...) are allowed. For any other scheme this is invalid.

Смотрите также

pathinfo()
parse_str()
dirname()
basename()



parse_url
christopher DOT aiken AT gmail DOT com
18-Jul-2006 01:58
I was looking for a very simple way to get the absolute domain names of hosts that make posts to my scripts. I wanted to check that the absolute domain (not the fully qualified host) was legitimate in mysql db.

I came up with this as it feels simple and clean.

<?php

/*
 * Christopher Aiken
 * Revised: 7/18/2006
 * Parses and shows the host and absolute domain
 * from the previous page that referred to this current page.
 *
 * Very useful to check that a domain is allowed to
 * reference / call a script especially for submissions.
 *
 */
 
if (isset($_SERVER['HTTP_REFERER']))
{
 
$referer = parse_url($_SERVER['HTTP_REFERER']);
 
 
$host = $referer['host'];
  echo
'Host is: '.$host.'<br>';
 
 
$host = str_replace(".","/",$host);
 
 
$domain = dirname($host).'.'.basename($host);
 
$domain = basename($domain);
 
  echo
'Domain is: '.$domain.'<br>';
 
}

?>
corgilabs at SPAM_NO_THANK_YOUgmail dot com
13-Jul-2006 11:59
I hope this is helpful! Cheers!
-eo

<?

# Author: Eric O
# Date: July 13, 2006
# Go Zizou!! :O)

# Creating Automatic Self-Redirect To Secure Version
# of Website as Seen on Paypal and other secure sites
# Changes HTTP to HTTPS

#gets the URI of the script
$url $_SERVER['SCRIPT_URI'];

#chops URI into bits BORK BORK BORK
$chopped = parse_url($url);

#HOST and PATH portions of your final destination
$destination = $chopped[host].$chopped[path];

#if you are not HTTPS, then do something about it
if($chopped[scheme] != "https"){

#forwards to HTTP version of URI with secure certificate
header("Location: https://$destination");

exit();

}

?>
Vladimir Kornea
12-May-2006 12:21
See Also http_build_query()

(editors: please add this function to "See Also" section of the official documentation.)
php dot net at NOSPAM dot juamei dot com
09-May-2006 04:18
Modfied version of glue_url to avoid error messages if the error_reporting is set high.

function glue_url($parsed)
{
   if (! is_array($parsed)) return false;
       $uri = isset($parsed['scheme']) ? $parsed['scheme'].':'.((strtolower($parsed['scheme']) == 'mailto') ? '':'//'): '';
       $uri .= isset($parsed['user']) ? $parsed['user'].($parsed['pass']? ':'.$parsed['pass']:'').'@':'';
       $uri .= isset($parsed['host']) ? $parsed['host'] : '';
       $uri .= isset($parsed['port']) ? ':'.$parsed['port'] : '';
       $uri .= isset($parsed['path']) ? $parsed['path'] : '';
       $uri .= isset($parsed['query']) ? '?'.$parsed['query'] : '';
       $uri .= isset($parsed['fragment']) ? '#'.$parsed['fragment'] : '';
   return $uri;
}
peyn at tlen dot pl
09-Mar-2006 11:26
a little bugfix to greg dot linton at gmail dot com function:

you have to change:
<?php
else
{
  
$ending = $var[ 0 ] . '=' . urlencode( $var[ 1 ] );
}
?>

with

<?php
else
{
   if(
$action == '+' )
   {
      
$ending = $var[ 0 ] . '=' . urlencode( $var[ 1 ] );
   }
}
?>

otherwise when using function like this
<?php
$url
= ChangeQuery( '-', 'test' );
echo
$url;
?>

you will see: index.php?t=e

best regards
Tyron Madlener
15-Feb-2006 02:24
Oh, missed something. It should be HEAD instead of GET, because it only needs to read the header of the http response.
Tyron Madlener
15-Feb-2006 01:15
I needed to get information about the real URL, because some URL are just redirects to the real one. This function here tracks down the real URL as long as it gets redirects (errorcode 301,302, 303, 305 or 307) as response.
In this example i resolve my homepage www.tyron.at which redirects to a subdirectory.

$real_url = ResolveURL("http://www.tyron.at");

echo "<pre>";
print_r(parse_url($real_url));

function ResolveURL($url) {
  $info = parse_url($url);
  
  //echo "url: '$url'<br><pre>";
  //print_r($info);
  $fp = fsockopen($info['host'],80);

  if($fp) {
   $path = $info['path'];
   if(!strlen($path)) $path = "/";
   if(strlen($info['query'])) $path.="?".$info['query'];

   $out  = "GET $path HTTP/1.1\r\n";
   $out .= "Host: ".$info['host']."\r\n";
   $out .= "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.8) Gecko/20050511  Firefox/1.0.4\r\n";
   $out .= "Connection: Close\r\n\r\n";   
   fwrite($fp, $out);

   if(ereg("HTTP/1.1 30(1|2|3|5|7)",$resp = fgets($fp,512))) {     
     while (!feof($fp)) {
       if(preg_match("/Location: (.*)$/",$line=fgets($fp, 1024),$matches))
         $url = ResolveURL(chop($matches[1]));
     }
   }
   //echo $resp;
   fclose($fp);
  }
  return $url;
}
12-Jan-2006 03:42
small bugfix to greg dot linton at gmail dot com's very handy changeQuery - blank URIs weren't being processed correctly.

<?php
// line dealing with blank URI's:
$ending = $varName . '=' . urlencode($varVal);

// works if changed to:
$ending = $var[0] . '=' . urlencode($var[1]);

?>
greg dot linton at gmail dot com
30-Dec-2005 01:14
I needed to work both ways (adding & deleteing) query items to the url. Corey's function worked well for adding, but I needed the opposite. I modifed his to work for both ways leaving me with this:
<?php

/**
 * Edit the Query portion of an url
 *
 * @param    string    $action    ethier a "+" or a "-" depending on what action you want to perform
 * @param    mixed    $var    array (+) or string (-)
 * @param    string    $uri    the URL to use. if this is left out, it uses $_SERVER['PHP_SELF']
 * @version      1.0.0
 */
function ChangeQuery($action, $var = NULL, $uri = NULL) {

       if ((
$action == "+" && ! is_array($var))
             ||
           (
$action == "-" && $var == "")
             ||
          
$var == NULL)
               return
FALSE;

   if (
is_null($uri)) {//Piece together uri string
      
$beginning = $_SERVER['PHP_SELF'];
      
$ending = ( isset($_SERVER['QUERY_STRING']) ) ? $_SERVER['QUERY_STRING'] : '';
   } else {
      
$qstart = strpos($uri, '?');
       if (
$qstart === false) {
          
$beginning = $uri; //$ending is '' anyway
      
} else {
          
$beginning = substr($uri, 0, $qstart);
          
$ending = substr($uri, $qstart);
       }
   }

   if (
strlen($ending) > 0) {
      
$vals = array();
      
$ending = str_replace('?','', $ending);
      
parse_str($ending, $vals);
               if (
$action == "+")
                      
$vals[$var[0]] = $var[1];
      
$ending = '';
      
$count = 0;
       foreach(
$vals as $k => $v) {
           if (
$action == "-" && $k == $var) continue;
           if (
$count > 0) { $ending .= '&'; }
           else {
$count++; }
          
$ending .= "$k=" . urlencode($v);
       }
   } else {
          
$ending = $varName . '=' . urlencode($varVal);
   }

  
$result = $beginning . '?' . $ending;

   return
$result;
}
?>

with this test:
<?php
$url
= "http://www.somesite.com/somepage.php?id=53&sec=1&sort=up";

$url = ChangeQuery("+",array("test",5),$url);
echo
$url."<br>";
$url = ChangeQuery("-","sort", $url);
echo
$url."<br>";
$url = ChangeQuery("-","test", $url);
echo
$url."<br>";
$url = ChangeQuery("+",array("sort","dn"), $url);
echo
$url."<br>";

?>

I got
http://www.somesite.com/somepage.php?id=53&sec=1&sort=up&test=5
http://www.somesite.com/somepage.php?id=53&sec=1&test=5
http://www.somesite.com/somepage.php?id=53&sec=1
http://www.somesite.com/somepage.php?id=53&sec=1&sort=dn

?>
If you're adding to the url, the second argument has to be an array, where the first element is the name and the second is the value. If you're deleting from the query, it's the name of var to delete

I hope this helps somebody down the line.
jon _at_ gaarsmand _dot_ com
02-Aug-2005 12:51
Some developers look here for a mean of validating an url. So here is a simple way of validating an url.

$uri = 'http://some-domain-name.org';
if( preg_match( '/^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}'
       .'((:[0-9]{1,5})?\/.*)?$/i' ,$uri))
{
  echo $uri . ' is a valid url';
}
else
{
  echo $uri . ' is NOT a valid url';
}

Beware - it only validates scemes: http and https, and it only takes into account host and port part of the uri. It does not accept username and password.

For an email validator you could look at http://gaarsmand.com/index.php/IT_l%F8sninger/Kode_eksempler/PHP_kode.
scott a t connerly d o t net
06-Mar-2005 11:34
re: <b>osfist at yahoo dot com</b>'s http_implode function. 
Here is a companion function for that:

  function http_explode($stringInput) {
   if (! is_string($stringInput))
     return false;
   $arr_query=NULL;
   $args=explode('&',$stringInput);
   foreach($args as $arg) {
     $parts=explode('=',$arg);
     $arr_query[$parts[0]]=$parts[1];
   } return $arr_query;
  }
TheShadow
30-Dec-2004 12:36
You may want to check out the PEAR NET_URL class. It provides easy means to manipulate URL strings.

http://pear.php.net/package/Net_URL
corey at eyewantmedia dot com
22-Dec-2004 09:18
Just in case this helps someone, this is a quick and dirty way to add or replace values to your query string, which I found especially useful when modifying urls to allow paging through resultsets.

/**
 * @return string
 * @param string $varName
 * @param string $varVal
 * @param string $uri
 * @desc Returns the a string that is either
 *        $uri if you pass it or the current
 *        uri with the variable name $varName
 *        equal to the value urlencode($varVal)
 *        It replaces a current value if it find
 *        it or adds the variable and value pair
 *        if they are new.
*/
function AddToQuery($varName, $varVal, $uri=null) {
   $result = '';
   $beginning = '';
   $ending = '';
  
   if (is_null($uri)) {//Piece together uri string
       $beginning = $_SERVER['PHP_SELF'];
       $ending = ( isset($_SERVER['QUERY_STRING']) ) ? $_SERVER['QUERY_STRING'] : '';
   } else {
       $qstart = strpos($uri, '?');
       if ($qstart === false) {
           $beginning = $uri; //$ending is '' anyway
       } else {
           $beginning = substr($uri, 0, $qstart);
           $ending = substr($uri, $qstart);
       }
   }
  
   if (strlen($ending) > 0) {
       $vals = array();
       $ending = str_replace('?','', $ending);
       parse_str($ending, $vals);
       $vals[$varName] = $varVal;
       $ending = '';
       $count = 0;
       foreach($vals as $k => $v) {
           if ($count > 0) { $ending .= '&'; }
           else { $count++; }
           $ending .= "$k=" . urlencode($v);
       }
   } else {
       $ending = $varName . '=' . urlencode($varVal);
   }
  
   $result = $beginning . '?' . $ending;
  
   return $result;
}
duellj at gmail dot com
12-Oct-2004 03:13
A quick note about something that tripped me up:

the url you are parsing must include the scheme, or it will be parsed into the 'path' key.
Example:
<?
$parsed
= parse_url("www.php.net");
print_r($parsed);

/*
outputs:
Array
(
   [path] => www.php.net
)
*/
?>
esm at baseclass dot modulweb dot dk
17-Aug-2004 06:32
Hi

I did an URL Validator that also parses the URL into subparts. The validator does not use PHP specific functions, so it can be easily ported to javascript or another language. If you are looking at this page, chances are my validator might interest you.

http://baseclass.modulweb.dk/urlvalidator

Regards
Aceb
matt at cryptography dot com
09-May-2004 01:36
Modified version of glue_url()
Cox's,Anonimous fucntion

<?php
function glue_url($parsed) {
   if (!
is_array($parsed)) return false;
      
$uri = $parsed['scheme'] ? $parsed['scheme'].':'.((strtolower($parsed['scheme']) == 'mailto') ? '':'//'): '';
      
$uri .= $parsed['user'] ? $parsed['user'].($parsed['pass']? ':'.$parsed['pass']:'').'@':'';
      
$uri .= $parsed['host'] ? $parsed['host'] : '';
      
$uri .= $parsed['port'] ? ':'.$parsed['port'] : '';
      
$uri .= $parsed['path'] ? $parsed['path'] : '';
      
$uri .= $parsed['query'] ? '?'.$parsed['query'] : '';
      
$uri .= $parsed['fragment'] ? '#'.$parsed['fragment'] : '';
  return
$uri;
}
?>
osfist at yahoo dot com
29-Feb-2004 11:11
Functions to edit a url query key and its value.
You can also add a new query key and its value.

I gathered and modified useful functions for my code.
It works fine as you see at the test result.

<?php
function get_query_edited_url($url, $arg, $val) {
  
$parsed_url = parse_url($url);
  
parse_str($parsed_url['query'],$url_query);
  
$url_query[$arg] = $val;
  
  
$parsed_url['query'] = http_implode($url_query);
  
$url = glue_url($parsed_url);
   return
$url;
}

function
http_implode($arrayInput) {
   if (!
is_array($arrayInput))
       return
false;

  
$url_query="";
   foreach (
$arrayInput as $key=>$value) {
      
      
$url_query .=(strlen($url_query)>1)?'&':"";
      
$url_query .= urlencode($key).'='.urlencode($value);
   }
   return
$url_query;
}

function
glue_url($parsed) {
   if (!
is_array($parsed))
       return
false;
  
  
$url = $parsed['scheme'] ? $parsed['scheme'].':'
      
.((strtolower($parsed['scheme']) == 'mailto') ? '':'//'): '';
  
$url .= $parsed['user'] ? $parsed['user']
       .(
$parsed['pass']? ':'.$parsed['pass']:'').'@':'';
  
$url .= $parsed['host'] ? $parsed['host'] : '';
  
$url .= $parsed['port'] ? ':'.$parsed['port'] : '';
  
$url .= $parsed['path'] ? $parsed['path'] : '';
  
$url .= $parsed['query'] ? '?'.$parsed['query'] : '';
  
$url .= $parsed['fragment'] ? '#'.$parsed['fragment'] : '';
   return
$url;
}

/* Test & Output

$url =
"http://user:pass@host/path?arg1=value&arg2=myval2#anchor";
print  "<br>0:".$url;
print  "<br>1:".get_query_edited_url($url,'arg1','CHANGED'); //Arg1
print  "<br>2:".get_query_edited_url($url,'arg2','CHANGED'); //Arg2
print  "<br>3:".get_query_edited_url($url,'arg3','NEW'); //New Argument
*/

// Output
//http://user:pass@host/path?arg=value&arg2=myval2#anchor
//http://user:pass@host/path?arg=value&arg2=CHANGED#anchor
//http://user:pass@host/path?arg=CHANGED&arg2=myval2#anchor
?>
alan at zeroasterisk dot com
22-Dec-2003 01:06
<?
/*
Alan -- here is a useful function for displaying links...  if you don't do this, an improper query string could mess up html code...  (by having a > or " or something...)

If you have simple improvements or flaws, please email me. [at]zeroasterisk[d0t]com
*/

function linkprep($link)
   {
      
$link_array=parse_url($link);
    
$return= str_replace($link_array['query'], rawurlencode($link_array['query']), $link);
    
$return= str_replace($link_array['fragment'], rawurlencode($link_array['fragment']), $return);
     return
$return;
   }

?>
sjt at 5jt dot com
21-Oct-2003 07:45
It gets better...

parse_str($_SERVER['QUERY_STRING']);

though you might flinch at random names from the URI query string showing up as variables. Safer to secure them in a hash table, eg

   parse_str($_SERVER['QUERY_STRING'],$vars);
   $lang = $vars['lang'];
   echo "Your language is $lang";

sjt
bermi.ferrer ) a t ( akelos dot com
01-Feb-2003 03:23
This is a small update for Steve's function. It removes the Argument even if its repeated more than once in the URL.

This function performance is better than the one I posted before (delete_value_from_url).

 function RemoveArgFromURL($URL,$Arg)
 {
    
   while($Pos = strpos($URL,"$Arg="))
   {

     if ($Pos)
     {
       if ($URL[$Pos-1] == "&")
       {
         $Pos--;
       }
       $nMax = strlen($URL);
       $nEndPos = strpos($URL,"&",$Pos+1);

       if ($nEndPos === false)
       {
       $URL = substr($URL,0,$Pos);
       }
       else
       {
         $URL = str_replace(substr($URL,$Pos,$nEndPos-$Pos),'',$URL);
       }
     }
   }
   return $URL;
 }
steve at mg-rover dot org
24-Jan-2003 09:59
An alternative and more straightforward to the remove an argument from a URL code above is below. I'm not saying its any better than the one above, but its easier to read ;) :p

----------------
  function RemoveArgFromURL($URL,$Arg)
  {
   $Pos = strpos($URL,"$Arg=");
  
   if ($Pos)
   {
     if ($URL[$Pos-1] == "&")
     {
       // If Pos-1 is pointing to a '&' knock Pos back 1 so its removed.
       $Pos--;
     }
     $nMax = strlen($URL);
     $nEndPos = strpos($URL,"&",$Pos+1);

     if ($nEndPos === false)
     {
       // $Arg is on the end of the URL
       $URL = substr($URL,0,$Pos);
     }
     else
     {
       // $Arg is in the URL
       $URL = str_replace(substr($URL,$Pos,$nEndPos-$Pos),'',$URL);
     }
   }
   return $URL;
  }
----------------
Anonimous
09-May-2002 05:51
Modified version of glue_url() Cox's fucntion.
----------------------------------------------

// $parsed is a parse_url() resulting array
function glue_url($parsed) {
  
   if (! is_array($parsed)) return false;

   if (isset($parsed['scheme'])) {
     $sep = (strtolower($parsed['scheme']) == 'mailto' ? ':' : '://');
     $uri = $parsed['scheme'] . $sep;
   } else {
     $uri = '';
   }
 
   if (isset($parsed['pass'])) {
     $uri .= "$parsed[user]:$parsed[pass]@";
   } elseif (isset($parsed['user'])) {
     $uri .= "$parsed[user]@";
   }
 
   if (isset($parsed['host']))    $uri .= $parsed['host'];
   if (isset($parsed['port']))    $uri .= ":$parsed[port]";
   if (isset($parsed['path']))    $uri .= $parsed['path'];
   if (isset($parsed['query']))    $uri .= "?$parsed[query]";
   if (isset($parsed['fragment'])) $uri .= "#$parsed[fragment]";
 
   return $uri;
}

<http_build_queryrawurldecode>
 Last updated: Tue, 15 Nov 2005