如何使用 PHP 查找域是 HTTP 还是 HTTPS(有或没有 WWW)?

How to find the domain is whether HTTP or HTTPS (with or without WWW) using PHP?

我有 百万 (1,000,000) 列表。

+----+--------------+--------------------------+
| Id | Domain_Name  |       Correct_URL        |
+----+--------------+--------------------------+
|  1 | example1.com | http://www.example1.com  |
|  2 | example2.com | https://exmple2.com      |
|  3 | example3.com | https://www.example3.com |
|  3 | example4.com | http://example4.com      |
+----+--------------+--------------------------+

问题: 我需要填写Correct_URL栏。

我面临的问题是如何找到域名前的前缀部分。它可能是 http://http://www.https://https://www.

如何使用 PHP 正确找到以上 4 中的内容?请注意,我需要 运行 对所有 1,000,000 个域进行编码....所以我正在寻找最快的检查方法...

除了向每种可能性发出 HTTP 请求并查看是否得到响应之外,没有其他办法。

当您断言 "It may either http:// or http://www. or https:// or https://www." 时,现实世界的域可能会提供零、部分或全部或那些(以及其他各种),并且它们可能会响应请求确定或重定向或身份验证错误等

HTTP 和 HTTPS 不是 Web 应用程序的属性;它们是由端点(Web 服务器或应用程序防火墙等)处理的通信协议。

与任何网络通信一样,必须分别探测主机("www" 是主机)和端口(不一定,但最常见)端口 80 和 443。这个探测就是喊一声,那你等着看对面有没有服务在监听。

给定一个已知的 url 你可以用 get_headers 调用 http and/or https 版本,从他们你可以确定 https 是否可用,如果 http 重定向到 https 和依此类推

可在此处找到详细信息:http://php.net/manual/en/function.get-headers.php

您可以使用 cURL 方法:

$url_list = ['facebook.com','google.com'];

foreach($url_list as $url){

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch,CURLOPT_USERAGENT,'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13');
    curl_exec($ch);

    $real_url =  curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
    echo $real_url;//add here your db commands

}

这个需要一些时间,因为它需要最后一次重定向 url。如果你只想检查它是 http 还是 https 你可以试试这个:

$url_list = ['facebook.com','google.com'];

foreach($url_list as $url){

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_exec($ch);

    $real_url =  curl_getinfo($ch, CURLINFO_REDIRECT_URL);
    echo $real_url;//add here your db commands

}

所以我不得不构建一个类似的系统来验证用户提供的 URL。

最后,您需要设置一个优先级顺序,推荐的顺序是 HTTPS 优先于 HTTP,WWW 优先于无,因此您最终得到的优先级列表如下:

正如其他人所说,您需要使用 cURL 来测试这些。

foreach($domainRows as $domainRow){
    $scheme_list = ['https://www.','https://', 'http://www.', 'http://'];
    $bestUrl = false;
    foreach($scheme_list as $scheme){

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $scheme.$domainRow['Domain_Name']);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch,CURLOPT_USERAGENT,'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13');
        curl_exec($ch);

        $real_url =  curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
        if($real_url){
            $bestUrl = $scheme.$domainRow['Domain_Name']
            break;
        }
    }


    if($bestUrl){
        // you have the best URL to use as $bestUrl save it to your DB Row
    }else{
        // the site is not responding to any URL's do you need to do something here?
    }

}

或者根据我完全忘记的 Alexander Holman 的回答 get_headers 你可以做到

foreach($domainRows as $domainRow){
    $scheme_list = ['https://www.','https://', 'http://www.', 'http://'];
    $bestUrl = false;
    foreach($scheme_list as $scheme){

        $res = get_headers($scheme.$domainRow['Domain_Name']);
        // if you want to allow redirects remove/alter this part as it blocks them.
        if($res && isset($res[0])){
            $statusParts = explode(" ", $res[0]);
            if($statusParts[1] == "200"){
                $bestUrl = $scheme.$domainRow['Domain_Name'];
                break;
            }
        }
        //end of status check
        //replace with below to allow all responses from server including 404
        /*if($res){
            $bestUrl = $scheme.$domainRow['Domain_Name'];
            break;
        }*/
    }


    if($bestUrl){
        // you have the best URL to use as $bestUrl save it to your DB Row
    }else{
        // the site is not responding to any URL's do you need to do something here?
    }

}

此代码将按优先顺序进行测试,第一个匹配的系统将停止对其他系统的测试,如果没有找到可用的系统,它会告诉您。

感谢 Supun Praneeth,我已经采用并扩充了那里的代码以更好地满足您的需求。