How To Get Redirect URL In PHP

HTTP redirects usually have the response status 301 or 302 and provide the redirection URL in the “Location” header. I’ve written three complementary PHP functions that you can use to find out where an URL redirects to (based on a helpful thread at WebmasterWorld). You don’t even need CURL for this – fsockopen() will do just fine.

The PHP script

/**
 * get_redirect_url()
 * Gets the address that the provided URL redirects to,
 * or FALSE if there's no redirect. 
 *
 * @param string $url
 * @return string
 */
function get_redirect_url($url){
	$redirect_url = null; 

	$url_parts = @parse_url($url);
	if (!$url_parts) return false;
	if (!isset($url_parts['host'])) return false; //can't process relative URLs
	if (!isset($url_parts['path'])) $url_parts['path'] = '/';
	 
	$sock = fsockopen($url_parts['host'], (isset($url_parts['port']) ? (int)$url_parts['port'] : 80), $errno, $errstr, 30);
	if (!$sock) return false;
	 
	$request = "HEAD " . $url_parts['path'] . (isset($url_parts['query']) ? '?'.$url_parts['query'] : '') . " HTTP/1.1\r\n"; 
	$request .= 'Host: ' . $url_parts['host'] . "\r\n"; 
	$request .= "Connection: Close\r\n\r\n"; 
	fwrite($sock, $request);
	$response = '';
	while(!feof($sock)) $response .= fread($sock, 8192);
	fclose($sock);

	if (preg_match('/^Location: (.+?)$/m', $response, $matches)){
		if ( substr($matches[1], 0, 1) == "/" )
			return $url_parts['scheme'] . "://" . $url_parts['host'] . trim($matches[1]);
		else
			return trim($matches[1]);
 
	} else {
		return false;
	}
	
}

/**
 * get_all_redirects()
 * Follows and collects all redirects, in order, for the given URL. 
 *
 * @param string $url
 * @return array
 */
function get_all_redirects($url){
	$redirects = array();
	while ($newurl = get_redirect_url($url)){
		if (in_array($newurl, $redirects)){
			break;
		}
		$redirects[] = $newurl;
		$url = $newurl;
	}
	return $redirects;
}

/**
 * get_final_url()
 * Gets the address that the URL ultimately leads to. 
 * Returns $url itself if it isn't a redirect.
 *
 * @param string $url
 * @return string
 */
function get_final_url($url){
	$redirects = get_all_redirects($url);
	if (count($redirects)>0){
		return array_pop($redirects);
	} else {
		return $url;
	}
}

Here’s an example that lists all URLs that a given address redirects to (in order) :

$rez = get_all_redirects('http://daerils.gtrends.hop.clickbank.net/');
print_r($rez);

Known Issues

Most likely you won’t ever run into one of these, but here they are anyway :

  • The script doesn’t recognize infinite redirects that don’t form a loop. However, it can handle normal redirection loops – get_all_redirects() exits as soon as it encounters an URL that it has already seen.
  • Relative redirects multiple (e.g. “Location: go.php?asdf”) won’t be fully followed by get_all_redirects().
  • Not an issue per-se, yet something to note : these functions won’t tell you if an URL is valid, just what it redirects to (if anything).

On a related note, check out the Firefox extension Redirect Remover.

Related posts :

60 Responses to “How To Get Redirect URL In PHP”

  1. White Shadow says:

    Interesting. I added syntax highlighting to your code.

  2. very nice script – thanks for sharing!

  3. Thomas says:

    Thanks for your work. I recently faced a similar problem and your solution made my day lots of easier.

    Thomas

  4. Rohit says:

    Thanks to all, on the net, i was able to get the redirect working, with some help.. code below

    I added this to the top of the code, now space or no space it works good.

    $mob = str_replace(“+”, “_”, $_SERVER[‘QUERY_STRING’]);
    $url = “http://example.com/pfinder?” . “$mob”;

    and at the end i added this to go to the page i want
    $fin = get_final_url($url);
    $mov = parse_url($fin, PHP_URL_QUERY);
    sleep(5);
    header(“Location: http://enample1.com?$mov“);

    works fine..
    But now i have a problem, the server i was to put this on does not support PHP. (server side)
    I know this is not the right forum, but can any one help me to get this done in javascript (client side)

  5. Yogesh Mathur says:

    That’s what I was looking for, Thanks a lot man.

  6. Manish singh says:

    HI Emprivo,
    I used your code but its not work, when I used below mention link its give me original url not redirected url.

    I have Linux OS and Mozilla browser

    and URL=http://legal-tb.auto-graphics.com/loginModule/Referrer.aspx?myses=16965&w=S&k=712481&cuid=legal&cusrvr=cassiopia&s=wdb&ltis=4&ltype=f&lmethod=1001&url=https%3a%2f%2fwww.lexis.com%2fresearch%2fretrieve%3f_m%3dd8ca55f1090c4475c89026e5fbc07401%26docnum%3d4%26_fmtstr%3dFULL%26_startdoc%3d1%26wchp%3ddGLbVzz-zSkAz%26_md5%3de4dd13f6ce45966fc41fc00c665ad0c1&bof=0&clientId=ACME-ACME2-C1235

    is the problem of Linux OS

    Please advise me where is I am wrong

  7. TMG says:

    Nice clean script. I added a couple of lines to handle websites that connect, but take way too long to load (so you can skip them):

    while(!feof($sock)) $response .= fread($sock, 8192);

    becomes:

    stream_set_timeout($sock, 1);
    while(!feof($sock)) {
    $meta = stream_get_meta_data($sock);
    if ($meta[‘timed_out’]) break;
    $response .= fread($sock, 8192);
    }

    (set the stream timeout to whatever you want in seconds, or 0,X where X is ms)

  8. JC says:

    This is a great script. Works perfectly for most redirections I find. I’m working with one instance where the site somehow knows that this is essentially a bot testing the link and not a normal browser. I have this same problem using CURL-based solutions.

    Any ideas how I can determine the final URL in a way that will fool these sites into redirecting as normal? Somehow it needs to simulate how the site handles the situation when a normal user visits the original URL. Ideas?

  9. White Shadow says:

    If at all possible, don’t. Anti-bot measures are sometimes very sophisticated, and finding a way to fool them can take a lot of time. Is that one site really worth it?

    That said, the first thing I’d suggest would be using a HTTP sniffer to check what headers a normal browser sends when opening that site, and modifying the script to send the same or similar headers. This might fool a primitive bot detector.

  10. George says:

    Great script, it does not currently detect Meta Refresh redirects though. There are quite a few of those as well unfortunately. 🙂

  11. White Shadow says:

    See Emprivo’s comment about detecting JavaScript redirects. You could use a similar approach to detect Meta refresh redirects, too.

  12. […] la soluzione al problema inizialmente sul forum di WebmasterWorld e, successivamente, sul blog W-Shadow. Quest’ultimo script può essere scaricato anche da questa pagina. Condividi […]

  13. Seb says:

    Awesome stuff, I’ve been wanting something to grab those redirects for a while and your functions worked perfectly! Cheers!

  14. Manatane says:

    Hello all,

    The script work fine with the url given as exempe, but it doesn’t work at all with feed proxy. For example, with this URL : http://www.spielefilmetechnik.de/feed.cfm?rubrik=Technik

    The function return me the original url.

    I tested with many URL feeds … any ideas ?

  15. White Shadow says:

    The URL “http://www.spielefilmetechnik.de/feed.cfm?rubrik=Technik” is not actually a redirect, so I’d say the script is working as expected. I tested the feed URL in several browsers and it was not redirected in any of them.

  16. Hernan says:

    You rock! work’s perfect! thanks a lot!

  17. halcyon says:

    Awesome. It took more time to search and find this site than it took to actually implement. My sincere thanks.

  18. Nuno says:

    Tank you. Tank you very much for this script. So cool. Tank you again.

  19. Leo Plaw says:

    Excellent script! You saved me heaps of time. Thank you very much. I’ve put your credits in the header of the code.

  20. Zack Katz says:

    Thanks for your code – it was useful in determining the canonical tag for a CubeCart installation.

Leave a Reply