#日期: 2008/11/12 01:17
在PHP中得到重定向 URL (redirect URL) 可以考虑使用下面三种方案来实现:
PHP代码如下:
$opts = array('http' => array( 'follow_location' => 0, 'max_redirects' => 1 ) ); $context = stream_context_create($opts); $result = file_get_contents('http://example.com/submit.php', false, $context); var_dump($http_response_header); # 响应头组成的数组 $redirect_url = null; foreach($http_response_header as $line){ if(preg_match('/^Location:(.+)/', $line, $matches)) $redirect_url = $matches[1]; }
上面代码中的$http_response_header
是系统变量。
也可以通过get_headers($url)
函数来实现(注意系统默认Stream Context被改变了)。
stream_context_set_default(array('http' => array( 'follow_location' => 0, 'max_redirects' => 1 ) )); $headers = get_headers('http://example.com', 1); $redirect_url = $headers['Location'];
下面的实现方法转自 How To Get Redirect URL In PHP
由于重定向之后的URL有可能再次redirect,下面的实现提供了三个函数:
get_redirect_url($url)
: 获取第一次redirct的URLget_all_redirects($url)
: 获取所有重定向URL的数组get_final_url($url)
: 获取最后一次重定向的URL/** * 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)){ 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; } }