PHP函数file_get_contents()访问腾讯云CDN地址超时的问题

oy4年前 (2022-04-24)技术研究3211

最近把一个域名迁移到了腾讯云CDN上,结果其他php程序出现了超时打不开的情况,最终定位到原因竟是,php代码中的file_get_contents()获取了用了腾讯云CDN的网址导致超时。


复现该问题很简单,php写一行代码打开一个用了腾讯云CDN的网址文件:

echo file_get_contents('http://cdn.wms.rj1111.top/badman.txt');


60s才能打开页面,网上参阅了一些资料,确认腾讯云CDN服务器没有回复FIN ANK导致的,必须等待CDN侧所设定的socket时间超时后才算结束


具体可以参考这一篇文章,作者写的非常详细:

https://www.jianshu.com/p/42e0c4304b60


解决方法:

方法1、给file_get_contents()函数加上超时时间,如0.5s

$opts        = array("http" => array("method" => "GET", "timeout" => 0.5));
$context     = stream_context_create($opts);
$result      = @file_get_contents('http://cdn.wms.rj1111.top/badman.txt', false, $context);


问题是,0.5s无法保证网络已经获取到了此文件,如果超时时间设置过长,又导致程序访问缓慢,不推荐此方法


方法2、弃用file_get_contents(),改用curl封装自定义函数来访问,例如:

$data   = http($url, $params, $method = 'GET', array(), false);
function http($url, $params, $method = 'GET', $header = array(), $multi = false)
{
    $opts = array(
        CURLOPT_TIMEOUT        => 3,
        CURLOPT_RETURNTRANSFER => 1,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_SSL_VERIFYHOST => false,
        CURLOPT_HTTPHEADER     => $header,
        CURLOPT_HEADER         => 0, // 调试开启
    );
    /* 根据请求类型设置特定参数 */
    switch (strtoupper($method)) {
        case 'GET':
            $opts[CURLOPT_URL] = $url . '?' . http_build_query($params);
            break;
        case 'POST':
            // 提交原始数据$multi=true
            $params                   = $multi ? $params : http_build_query($params);
            $opts[CURLOPT_URL]        = $url;
            $opts[CURLOPT_POST]       = 1;
            $opts[CURLOPT_POSTFIELDS] = $params;
            break;
        case 'PUT':
            $params                      = $multi ? $params : http_build_query($params);
            $opts[CURLOPT_URL]           = $url;
            $opts[CURLOPT_CUSTOMREQUEST] = 'PUT';
            $opts[CURLOPT_POSTFIELDS]    = $params;
            break;
        case 'DELETE':
            $params                      = $multi ? $params : http_build_query($params);
            $opts[CURLOPT_URL]           = $url;
            $opts[CURLOPT_CUSTOMREQUEST] = 'DELETE';
            $opts[CURLOPT_POSTFIELDS]    = $params;
            break;
        default:
            exit('不支持的请求方式!');
            //throw new Exception('不支持的请求方式!');
    }
    /* 初始化并执行curl请求 */
    $ch = curl_init();
    curl_setopt_array($ch, $opts);
    $data  = curl_exec($ch);
    $error = curl_error($ch);
    curl_close($ch);
    if ($error) {
        exit('请求发生错误:' . $error);
        //throw new Exception('请求发生错误:' . $error);
    }
    return $data;
}

此方法可完美解决,推荐使用


方法3、如果不想改动太多代码,那么绑定一个不带CDN直接解析源站IP的域名来调用即可,例如:

echo file_get_contents('http://no-cdn.wms.rj1111.top/badman.txt');

这是最低成本的改动方式,推荐使用

相关文章

快速搭建php+mySQL环境

下载地址http://phpnow.org/download.html当前版本包含 Apache-2.2.14 / 2.0.63PHP-5.2.12ZendOptimizer-3.3.3MySQL-5…

安全删除USB设备不用点 一键快捷搞定

安全删除USB设备不用点 一键快捷搞定

一般情况下,当插入闪存或其他可移动USB存储设备时,在系统托盘区会显示出一个绿色的弹出图标,以便让我们安全卸载USB设备。而当我们完成操作,要安全删除该设备时,最简单的方法是用鼠标左键点击这个绿色的图…

你还只会用迅雷和百度搜索电影吗?

你还只会用迅雷和百度搜索电影吗?

由于涉及版权,大家应该知道在迅雷上搜索当前热门电影,总会被屏蔽搜索结果,而百度搜索出来的结果参差不齐,据我经验,很多标榜所谓免费下载的电影网站,90%都会带有种种令人反感的弹窗广告,有些可能还带病毒,…

关于禁止局域网中PPS等网络电视

关于禁止局域网中PPS等网络电视

 总所周知,像PPS UUsee等这样的网络电视依靠p2p原理工作,我们在使用此类软件观看电视的同时,也同时为他人进行上传,从而占用大量宝贵的上行带宽,导致整个局域网中网速极慢,严重影响他人…

QQ最新版本号(更新至QQ2011 Beta1)

[Versions]2101=<QQ2011 Beta1>2107=<QQ2011 Beta1 优先体验版>1C53=<腾讯QQ概念版>1F57=<QQ201…

电脑系统时间同步更新时提示“RPC服务器不可用”解决办法

在对电脑系统时间进行“自动与Internet时间服务器同步”的时候,一点击“立即更新”,就会出现提示:“RPC服务器不可用”。一…

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。