How to get final URL after following HTTP redirections in pure PHP?

后端 未结 5 2036
有刺的猬
有刺的猬 2020-11-29 03:41

What I\'d like to do is find out what is the last/final URL after following the redirections.

I would prefer not to use cURL. I would like t

5条回答
  •  悲&欢浪女
    2020-11-29 04:12

    Added to code from answers @xaav and @Houssem BDIOUI: 404 Error case and case when URL with no response. get_final_url($url) in that cases return strings: 'Error: 404 Not Found' and 'Error: No Responce'.

    /**
     * get_redirect_url()
     * Gets the address that the provided URL redirects to,
     * or FALSE if there's no redirect,
     * or 'Error: No Responce',
     * or 'Error: 404 Not Found'
     *
     * @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 'Error: No Responce';
    
        $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 .= "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36\r\n";
        $request .= "Connection: Close\r\n\r\n";
        fwrite($sock, $request);
        $response = '';
        while (!feof($sock))
            $response .= fread($sock, 8192);
        fclose($sock);
    
        if (stripos($response, '404 Not Found') !== false)
        {
            return 'Error: 404 Not Found';
        }
    
        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,
     * or 'Error: No Responce'
     * or 'Error: 404 Not Found',
     *
     * @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;
        }
    }
    

提交回复
热议问题