drupal用 cURL 代替 stream_socket_client解决Notice: Undefined variable: errno
在个别虚拟主机上 drupal_http_request 函数因为 stream_socket_client 被限制而报错:
Notice: Undefined variable: errno 在 drupal_http_request() (行 898 在 /data/home/xxx/htdocs/includes/common.inc).
Notice: Undefined variable: errstr 在 drupal_http_request() (行 899 在 /data/home/xxx/htdocs/includes/common.inc).
解决方案一种是修改源码,用fsockopen 函数代替,此种方法不推荐。推荐的方法是安装 chr 模块 ( https://www.drupal.org/project/chr ) ,用覆写的方法让cURL 代替原有的 stream_socket_client 即可。在开启了 chr 模块后,如果因为服务器的PHP开启了 safe_mode ,会有一个错误,按照错误提示,把 chr.module 中对应行注释掉,不使用curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true),
或者重新自定义一个函数,
function curl_redir_exec($ch,$debug="")
{
static $curl_loops = 0;
static $curl_max_loops = 20;
if ($curl_loops++ >= $curl_max_loops)
{
$curl_loops = 0;
return FALSE;
}
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
$debbbb = $data;
list($header, $data) = explode("\n\n", $data, 2);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($http_code == 301 || $http_code == 302) {
$matches = array();
preg_match('/Location:(.*?)\n/', $header, $matches);
$url = @parse_url(trim(array_pop($matches)));
//print_r($url);
if (!$url)
{
//couldn't process the url to redirect to
$curl_loops = 0;
return $data;
}
$last_url = parse_url(curl_getinfo($ch, CURLINFO_EFFECTIVE_URL));
/* if (!$url['scheme'])
$url['scheme'] = $last_url['scheme'];
if (!$url['host'])
$url['host'] = $last_url['host'];
if (!$url['path'])
$url['path'] = $last_url['path'];*/
$new_url = $url['scheme'] . '://' . $url['host'] . $url['path'] . ($url['query']?'?'.$url['query']:'');
curl_setopt($ch, CURLOPT_URL, $new_url);
// debug('Redirecting to', $new_url);
return curl_redir_exec($ch);
} else {
$curl_loops=0;
return $debbbb;
}
}
函数定义好后,curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true)这条语句替换为curl_redir_exec($ch)即可。