我正在尝试异步运行脚本。在Stackoverflow上找到如何做到这一点是没有问题的。问题是,我正在尝试我发现的一个例子,但它不起作用。脚本运行时不会在error_log中输出错误。
我的主php脚本:
function backgroundPost($url){
$parts=parse_url($url);
$fp = fsockopen($parts['host'],
isset($parts['port'])?$parts['port']:80,
$errno, $errstr, 30);
if (!$fp) {
return false;
} else {
$out = "POST ".$parts['path']." HTTP/1.1'r'n";
$out.= "Host: ".$parts['host']."'r'n";
$out.= "Content-Type: text/plain'r'n";
$out.= "Content-Length: ".strlen($parts['query'])."'r'n";
$out.= "Content-Length: ".strlen($parts['query'])."'r'n";
$out.= "Connection: Close'r'n'r'n";
if (isset($parts['query'])) $out.= $parts['query'];
fwrite($fp, $out);
fclose($fp);
return true;
}
}
//Example of use
backgroundPost('http://192.168.1.107/smic/testarea/runner.php?id=1');
fwrite()的响应为"155"。
backgroundPost正在返回"true"。
runner.php:
ignore_user_abort(true);
set_time_limit(50);
error_log("RUNNING!");
为什么"RUNNING!"注释被写入错误日志?这就像scipt实际上并没有执行一样。
当直接访问runner.php(在backgroundPost中发布URL)时,脚本会按预期工作。
两个脚本都具有apache:apache的777权限。
在上运行
- Linux/CNTOS 6.2
- PHP 5.3.3
- Apache 2.2.15
这可能与我使用的是经过身份验证的会话,而经过身份验证后的用户当然不是运行脚本的apache有关吗?
使用CURL进行测试
@jprofitt建议我也尝试过卷曲:
async_curl.php:
$ch = curl_init("http://192.168.1.107/");
$fp = fopen("http://192.168.1.107/smic/testarea/runner.php", "r");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC ) ;
curl_setopt($ch, CURLOPT_USERPWD, "kaand:xIWGWt0DNVriw");
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
$info = curl_getinfo($ch);
echo print_r($info);
curl_close($ch);
fclose($fp);
Tis是从curl_getinfo($ch):打印的
Array
(
[url] => http://192.168.1.107/
[content_type] => text/html; charset=UTF-8
[http_code] => 302
[header_size] => 411
[request_size] => 103
[filetime] => -1
[ssl_verify_result] => 0
[redirect_count] => 0
[total_time] => 0.002165
[namelookup_time] => 0.000106
[connect_time] => 0.000192
[pretransfer_time] => 0.000211
[size_upload] => 0
[size_download] => 0
[speed_download] => 0
[speed_upload] => 0
[download_content_length] => 0
[upload_content_length] => 0
[starttransfer_time] => 0.002109
[redirect_time] => 0
[certinfo] => Array
(
)
[redirect_url] => http://192.168.1.107/login.php
)
1
我确实尝试过$ch=curl_init("http://192.168.1.107/");然后我在网上收到了消息"需要授权"。在error_log中,我得到了运行php.所需的HTTP/1.1 401授权
在执行'curl_setopt($ch,CURLOPT_File,$fp);'时,我确实在error_log中收到了$fp"不是有效的文件句柄资源"的投诉。
数组末尾有一个重定向到登录页的问题,这可能与该问题有关吗?
所以,我遇到的问题与runner.php的限制区域有关。无论我使用curl还是fsockopen,我都需要验证请求。在这里,我包含了fsockopen和curl对受限区域进行异步请求的解决方案。
fsockopen:
function backgroundPost($url){
$parts=parse_url($url);
echo $parts['path']."<br/>";
echo $parts['host']."<br/>";
echo $url;
$fp = fsockopen($parts['host'],
isset($parts['port'])?$parts['port']:80,
$errno, $errstr, 10);
$auth = base64_encode("kaand:kaand123");
if (!$fp) {
return false;
} else {
$out = "POST ".$parts['path']." HTTP/1.1'r'n";
$out.= "Host: ".$parts['host']."'r'n";
$out.= "User-Agent: Anonymous'r'n";
$out.= "Content-Type: text/plain'r'n";
$out.= "Authorization: Basic ".$auth;
$out.= "Content-Length: ".strlen($parts['query'])."'r'n";
$out.= "Connection: Close'r'n'r'n";
if (isset($parts['query'])) $out.= $parts['query'];
fwrite($fp, $out);
fclose($fp);
return true;
}
}
使用示例:
backgroundPost('http://192.168.1.107/smic/testarea/runner.php?id=1');
卷曲:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://192.168.1.107/smic/testarea/runner.php");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC ) ;
curl_setopt($ch, CURLOPT_USERPWD, "kaand:kaand123"); //Don't use the sha1-value
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
runner.php
do whatever...
我想我会选择fsockopen,认为这是一个比超时更好的解决方案,因为超时会迫使你至少有一些等待时间。如果会有很多流量,哪怕1秒也能积累。。。