Php 如果启用了安全模式或在中设置了打开的basedir,则无法激活CURLOPT_FollowlLocation
当我运行这个脚本时(http://bizonbytes.com/miscellaneous/sharrre.php?url=https://bizonbytes.com&type=googlePlus): 重要注意事项Php 如果启用了安全模式或在中设置了打开的basedir,则无法激活CURLOPT_FollowlLocation,php,Php,当我运行这个脚本时(http://bizonbytes.com/miscellaneous/sharrre.php?url=https://bizonbytes.com&type=googlePlus): 重要注意事项 我没有PHP的经验,我只需要运行这个脚本 (sharre.php) 我看过其他类似的案例,但能找出问题所在 我已经打开了windows/php.ini并确保safe_mode=Off 我注意到open_basedir是这样设置的;开放式= 我需要在open_basedir中添加
- 我没有PHP的经验,我只需要运行这个脚本 (sharre.php)
- 我看过其他类似的案例,但能找出问题所在
- 我已经打开了windows/php.ini并确保safe_mode=Off
- 我注意到open_basedir是这样设置的;开放式=
- 我需要在open_basedir中添加一些内容吗
- 这是有关安装的php版本的详细信息的链接。看
感谢大家在这件事上的帮助请注意,这是一个安全警告。使用cURL,网站可以将脚本重定向到
file:///etc/passwd
,把周围的东西弄得乱七八糟。为了防止这种情况,只要设置了open_basedir,cURL就不会跟随位置。您必须手动跟踪它们,并手动检查所有跟踪位置是否也安全
实现的示例实现如下:
function curl_exec_follow(/*resource*/ $ch, /*int*/ &$maxredirect = null) {
$mr = $maxredirect === null ? 5 : intval($maxredirect);
if (ini_get('open_basedir') == '' && ini_get('safe_mode' == 'Off')) {
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $mr > 0);
curl_setopt($ch, CURLOPT_MAXREDIRS, $mr);
} else {
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
if ($mr > 0) {
$newurl = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
$rch = curl_copy_handle($ch);
curl_setopt($rch, CURLOPT_HEADER, true);
curl_setopt($rch, CURLOPT_NOBODY, true);
curl_setopt($rch, CURLOPT_FORBID_REUSE, false);
curl_setopt($rch, CURLOPT_RETURNTRANSFER, true);
do {
curl_setopt($rch, CURLOPT_URL, $newurl);
$header = curl_exec($rch);
if (curl_errno($rch)) {
$code = 0;
} else {
$code = curl_getinfo($rch, CURLINFO_HTTP_CODE);
if ($code == 301 || $code == 302) {
preg_match('/Location:(.*?)\n/', $header, $matches);
$newurl = trim(array_pop($matches));
} else {
$code = 0;
}
}
} while ($code && --$mr);
curl_close($rch);
if (!$mr) {
if ($maxredirect === null) {
trigger_error('Too many redirects. When following redirects, libcurl hit the maximum amount.', E_USER_WARNING);
} else {
$maxredirect = 0;
}
return false;
}
curl_setopt($ch, CURLOPT_URL, $newurl);
}
}
return curl_exec($ch);
}
PHP可以有多个.ini文件和不同级别的ini类型重写。在你的脚本中的某个地方运行
phpinfo()
,看看实际的本地有效设置是什么。@MarcB运行时,你会得到这些信息。我不认为这是一个合理的解决方案。我只是尝试了一下,效果很好。谢谢你的发帖。我已经使用了preg_match部分和我在解析URL的代码中已经使用过的类似设置,工作起来很有魅力:)它只是显示了PHP配置是多么愚蠢。我是一名PHP开发人员5年多了,从来没有听说过这件事。这不是安全,而是愚蠢。最好阻止对本地文件的重定向,或者curl模块应该实现这样的功能。它不应该是一个用户函数,而是对cURL和PHP交互方式的限制。cURL位于PHP外部,并通过扩展绑定。在此基础上构建了几个抽象层,已经解决了这个问题,但是curl_*API并不是一个高级的抽象层。
Warning: curl_setopt_array() [function.curl-setopt-array]: CURLOPT_FOLLOWLOCATION cannot be activated when safe_mode is enabled or an open_basedir is set in C:\Inetpub\vhosts\bizonbytes.com\httpdocs\miscellaneous\sharrre.php on line 56
{"url":"https://bizonbytes.com","count":""}
function curl_exec_follow(/*resource*/ $ch, /*int*/ &$maxredirect = null) {
$mr = $maxredirect === null ? 5 : intval($maxredirect);
if (ini_get('open_basedir') == '' && ini_get('safe_mode' == 'Off')) {
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $mr > 0);
curl_setopt($ch, CURLOPT_MAXREDIRS, $mr);
} else {
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
if ($mr > 0) {
$newurl = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
$rch = curl_copy_handle($ch);
curl_setopt($rch, CURLOPT_HEADER, true);
curl_setopt($rch, CURLOPT_NOBODY, true);
curl_setopt($rch, CURLOPT_FORBID_REUSE, false);
curl_setopt($rch, CURLOPT_RETURNTRANSFER, true);
do {
curl_setopt($rch, CURLOPT_URL, $newurl);
$header = curl_exec($rch);
if (curl_errno($rch)) {
$code = 0;
} else {
$code = curl_getinfo($rch, CURLINFO_HTTP_CODE);
if ($code == 301 || $code == 302) {
preg_match('/Location:(.*?)\n/', $header, $matches);
$newurl = trim(array_pop($matches));
} else {
$code = 0;
}
}
} while ($code && --$mr);
curl_close($rch);
if (!$mr) {
if ($maxredirect === null) {
trigger_error('Too many redirects. When following redirects, libcurl hit the maximum amount.', E_USER_WARNING);
} else {
$maxredirect = 0;
}
return false;
}
curl_setopt($ch, CURLOPT_URL, $newurl);
}
}
return curl_exec($ch);
}