You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP getimagesize()在HTTPS下触发Apache超时,HTTP下正常

解决PHP getimagesize()在HTTPS环境下超时的问题

根据你描述的情况——getimagesize()在HTTPS下出现和Apache超时时长一致的延迟,HTTP下正常,且图片仅32KB——我来帮你梳理可能的原因和解决方案:

1. 优先方案:直接使用本地文件路径(绕过HTTP/HTTPS请求)

你当前是通过HTTPS URL请求本地服务器上的图片,这完全没必要,反而会引入HTTP请求的开销和潜在的SSL握手问题。直接用本地文件路径调用getimagesize()就能彻底解决延迟问题:

echo "The start time is " . date("h:i:sa");
echo "<br>";
// 构建本地文件路径
$img_path = $_SERVER['DOCUMENT_ROOT'] . dirname($_SERVER['REQUEST_URI']) . "/assets/img/logo/45.jpg";
print $img_path;
echo "<br>";
echo "The time before getimagesize() is " . date("h:i:sa");
echo "<br>";
$img_dimen = getimagesize($img_path);
print_r($img_dimen);
echo "<br>";
echo "The time after getimagesize() is " . date("h:i:sa");
echo "<br>";

function url(){
    return sprintf(
        "%s://%s%s",
        isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off' ? 'https' : 'http',
        $_SERVER['SERVER_NAME'],
        dirname($_SERVER['REQUEST_URI'])
    );
}

这个方法跳过了所有HTTP/HTTPS的网络请求逻辑,直接读取本地文件,肯定不会有超时问题,也是性能最优的选择。

2. 如果必须使用HTTPS URL:排查SSL验证问题

PHP 5.6开始默认启用了严格的SSL证书验证,当你的本地HTTPS请求出现证书验证失败时,可能会导致请求重试直到超时。你可以临时关闭SSL验证来测试(仅用于排查,生产环境不建议这么做):

// 在调用getimagesize()前添加这段代码
stream_context_set_default(
    array(
        'ssl' => array(
            'verify_peer' => false,
            'verify_peer_name' => false,
        )
    )
);

// 原有的getimagesize()调用
$img_dimen = getimagesize($img_url);

如果这样修改后延迟消失,说明是证书验证的问题。你可以:

  • 确保PHP的openssl.cafile或openssl.capath配置指向正确的CA证书文件(比如Ubuntu上的/etc/ssl/certs/ca-certificates.crt)
  • 如果是自签名证书,将证书添加到PHP的信任列表中

3. 排查本地回环请求的解析/配置问题

当服务器自身访问自己的HTTPS域名时,可能出现DNS解析或Apache虚拟主机匹配的问题:

  • 修改/etc/hosts文件,将你的域名指向127.0.0.1,避免DNS解析到公网IP再绕回本地的延迟
  • 检查Apache的SSL虚拟主机配置,确保ServerName和ServerAlias与你请求的域名完全匹配,避免Apache在匹配虚拟主机时耗时
  • 检查Apache的ssl.conf配置,是否开启了OCSP Stapling但配置错误(比如OCSP服务器不可达),这会导致SSL握手时的超时

4. 替代方案:手动控制HTTP流的超时设置

如果必须使用URL请求,可以用file_get_contents配合自定义上下文来控制超时,再通过GD库获取图片尺寸,替代getimagesize():

echo "The start time is " . date("h:i:sa");
echo "<br>";
$img_url = url()."/assets/img/logo/45.jpg";
print $img_url;
echo "<br>";
echo "The time before fetching image is " . date("h:i:sa");
echo "<br>";

// 创建带有超时和SSL设置的上下文
$context = stream_context_create(array(
    'http' => array(
        'timeout' => 2, // 设置2秒超时,避免长时间挂起
    ),
    'ssl' => array(
        'verify_peer' => false,
        'verify_peer_name' => false,
    )
));

// 获取图片数据并解析尺寸
$img_data = file_get_contents($img_url, false, $context);
if($img_data){
    $img = imagecreatefromstring($img_data);
    $img_dimen = array(imagesx($img), imagesy($img));
    imagedestroy($img);
    print_r($img_dimen);
} else {
    echo "Failed to fetch image";
}

echo "<br>";
echo "The time after fetching image is " . date("h:i:sa");
echo "<br>";

function url(){
    return sprintf(
        "%s://%s%s",
        isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off' ? 'https' : 'http',
        $_SERVER['SERVER_NAME'],
        dirname($_SERVER['REQUEST_URI'])
    );
}

这个方法能更灵活地控制请求的超时和SSL设置,避免getimagesize()底层默认配置导致的超时。


内容的提问来源于stack exchange,提问作者Yamraj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:12:06