PHP CURL带有CURLOPT_FOLLOWLOCATION错误

10

我遇到了一个错误

当启用safe_mode或设置open_basedir时,无法激活CURLOPT_FOLLOWLOCATION

我在Google上找到了很多解决方案,但对于这个网站它们都不起作用。只需要CURLOPT_FOLLOWLOCATION。愚蠢的主机商不想启用safe_mode或open_basedir。我能否自己启用它们,也许创建一个带有一些参数的htaccess文件?

4个回答

13

这个错误意味着safe_mode或open_basedir被启用了(可能是open_basedir),如果您的主机有任何良好的安全设置,则可能无法覆盖它们。

所以你有两种选择:

1)更换主机(我想这不是一个理想的选择)

2)使用类似于在php curl_setopt页面中找到的函数,例如http://www.php.net/manual/en/function.curl-setopt.php#95027

以下是第二点中指定函数的修复版本。

function curl_redirect_exec($ch, &$redirects, $curlopt_header = false) {
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $data = curl_exec($ch);

    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    if ($http_code == 301 || $http_code == 302) {
        list($header) = explode("\r\n\r\n", $data, 2);

        $matches = array();
        preg_match("/(Location:|URI:)[^(\n)]*/", $header, $matches);
        $url = trim(str_replace($matches[1], "", $matches[0]));

        $url_parsed = parse_url($url);
        if (isset($url_parsed)) {
            curl_setopt($ch, CURLOPT_URL, $url);
            $redirects++;
            return curl_redirect_exec($ch, $redirects, $curlopt_header);
        }
    }

    if ($curlopt_header) {
        return $data;
    } else {
        list(, $body) = explode("\r\n\r\n", $data, 2);
        return $body;
    }
}

有趣的是,脚本在我的主机上(便宜且虚拟)运行良好,但老板使用愚蠢的主机并且没有改变的意愿。关于这个函数-我知道它,当我开始编写脚本时,我手动调用每个URL,但最后一个URL无法工作,只有使用CURLOPT_FOLLOWLOCATION才能帮助我。 - kusanagi
抱歉,我没有实际测试该函数,你是正确的,它不能正常工作(它假设Location标头不是最后一个)。我已经在我的答案中添加了一份我测试过的纠正版本。 - Rwky
1
您的解决方案存在一些错误。正则表达式应为 [^\n]。在递归调用 curl_redirect_exec 时,您应该传递 $curlopt_header - Kendall Hopkins
愚蠢的问题:我应该如何使用这个?当我尝试时,它显示“致命错误:无法通过引用传递参数2”。我使用了$xml = curl_redirect_exec($ch, true); - celliott1997

1
如果您使用 CURLOPT_REDIR_PROTOCOLS 指定了只允许重定向使用 http 和 https 协议,那么您就可以在不使用 safe_modeopen_basedir 的情况下使用 CURLOPT_FOLLOWLOCATION

2
CURLOPT_REDIR_PROTOCOLS设置为CURLPROTO_HTTP | CURLPROTO_HTTPS似乎无法解决open_basedir的问题。 - Mahn

0

你好,我修复了添加这个条件:

$safeMode = @ini_get('safe_mode');
$openBasedir = @ini_get('open_basedir');
if (empty($safeMode) && empty($openBasedir)) {
    curl_setopt($curl_handle, CURLOPT_FOLLOWLOCATION, true);
}else
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);

并在我的 .htaccess 文件中添加

php_flag safe_mode off
php_flag open_basedir off

2
你的 $curl 和 $curl_handle 变量是从哪里来的? - Craig

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接