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 :

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

  1. […] suis actuellement en utilisant un Script PHP de me l'URL redirigée un travail, mais bien sûr, cela est loin d'être idéale et potentiellement […]

  2. diegogarcia.dev says:

    I’ve a problem when I try to get_redirect_url(“https://es.gearbest.com/3d-printers-3d-printer-kits/pp_428456.html”);

    Php hangs here: while(!feof($sock)) $response .= fread($sock, 8192); but I don’t know why… It works for another links and for the root domain get_redirect_url(“https://es.gearbest.com”);

    Can you help me?

    Thanks.

  3. Michael says:

    This script saved me so much time!!! Thank you for your help and for publishing this!

  4. Diane says:

    Hi everyone,

    I’ve been trying to use the whole script in Google Sheets but I have encountered 2 Syntax errors so far.
    Please note that I have copy pasted the exact PHP script.

    Line 12: seems like I have to remove the “@” sign.
    Line 17: another syntax error, but I don’t know what it is exactly.
    …and there may be more, but I don’t know yet.

    Could you please help me out?

    My website is using lots of 301s and 302s. I’ve been using another script which easily finds 404 and 301 errors, but it has been identifying 302s as 200s. So, to fix that, I’ve been trying to find an intermediate solution: finding out if the ultimate URL differs from the original, which will then tell me if there’s a 302 error happening under the surface.

    Thank you,
    Diane

  5. Jānis Elsts says:

    The “@” sign is an error control operator that suppresses errors that might be generated by the expression that follows the operator. It’s not a syntax error, but it’s also not strictly required for this script to work, so you can remove it if you wish.

    As far as I can tell, there are no syntax errors on line 17. Which PHP version are you using?

Leave a Reply