问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

请php达人举个fsockopen post表单的例子

发布网友 发布时间:2022-04-29 09:28

我来回答

2个回答

懂视网 时间:2022-04-29 13:49

php执行一段程序,有可能几毫秒就执行完毕,也有可能耗时较长。

例如,用户下单这个事件,如果调用了些第三方服务进行发邮件、短信、推送等通知,可能导致前端一直在等待。

而有的时候,我们并不关心这些耗时脚本的返回结果,只要执行就行了。这时候就需要采用异步的方式执行。

众所周知,PHP没有直接支持多线程这种东西。我们可以采用折衷的方式实现。这里主要说的就是fsockopen

通过fsockopen发送请求并忽略返回结果,程序可以马上返回。

示例代码:

$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);
if (!$fp) {
 echo "$errstr ($errno)<br />
";
} else {
 $out = "GET /backend.php HTTP/1.1
";
 $out .= "Host: www.example.com
";
 $out .= "Connection: Close

";
 
 fwrite($fp, $out);
 /*忽略执行结果
 while (!feof($fp)) {
 echo fgets($fp, 128);
 }*/
 fclose($fp);
}

需要注意的是我们需要手动拼出header头信息。通过打开注释部分,可以查看请求返回结果,但这时候又变成同步的了,因为程序会等待返回结果才结束。

实际测试的时候发现,不忽略执行结果,调试的时候每次都会成功发送sock请求;但忽略执行结果,经常看到没有成功发送sock请求。查看nginx日志,发现很多状态码为499的请求。

后来找到了原因:

fwrite之后马上执行fclose,nginx会直接返回499,不会把请求转发给php处理。

客户端主动端口请求连接时,NGINX 不会将该请求代理给上游服务(FastCGI PHP 进程),这个时候 access log 中会以 499 记录这个请求。

解决方案:

1)nginx.conf增加配置

# 忽略客户端中断
fastcgi_ignore_client_abort on;

2)fwrite之后使用usleep函数休眠20毫秒:

usleep(20000);

后来测试就没有发现失败的情况了。

附上完整代码:

<?php
/**
 * 工具类
 * */
class FsockService {
 
 public static function post($url, $param){
 $host = parse_url($url, PHP_URL_HOST);
 $port = 80;
 $errno = '';
 $errstr = '';
 $timeout = 30;
 $data = http_build_query($param);
 // create connect
 $fp = fsockopen($host, $port, $errno, $errstr, $timeout);
 if(!$fp){
  return false;
 }
 // send request
 $out = "POST ${url} HTTP/1.1
";
 $out .= "Host:${host}
";
 $out .= "Content-type:application/x-www-form-urlencoded
";
 $out .= "Content-length:".strlen($data)."
";
 $out .= "Connection:close

";
 $out .= "${data}";
 fwrite($fp, $out);
 //忽略执行结果;否则等待返回结果
// if(APP_DEBUG === true){
 if(false){
  $ret = '';
  while (!feof($fp)) {
  $ret .= fgets($fp, 128);
  }
 }
 usleep(20000); //fwrite之后马上执行fclose,nginx会直接返回499
 fclose($fp);
 }
 public static function get($url, $param){
 $host = parse_url($url, PHP_URL_HOST);
 $port = 80;
 $errno = '';
 $errstr = '';
 $timeout = 30;
 $url = $url.'?'.http_build_query($param);
 // create connect
 $fp = fsockopen($host, $port, $errno, $errstr, $timeout);
 if(!$fp){
  return false;
 }
 // send request
 $out = "GET ${url} HTTP/1.1
";
 $out .= "Host:${host}
";
 $out .= "Connection:close

";
 fwrite($fp, $out);
 //忽略执行结果;否则等待返回结果
// if(APP_DEBUG === true){
 if(false){
  $ret = '';
  while (!feof($fp)) {
  $ret .= fgets($fp, 128);
  }
 }
 usleep(20000); //fwrite之后马上执行fclose,nginx会直接返回499
 fclose($fp);
 }
 
}
?>

更多相关php知识,请访问php教程!

热心网友 时间:2022-04-29 10:57

例子代码如下,里面的函数是从我的程序里面粘贴的,保证没有问题,我空间有用PHP写的开心农场、超级大富翁的自动挂机程序可以供你参考:

<?php
list($body,$header)=http_request('POST',
'http://www2.ctt.pt/feapl/jsp/pesqobjectos/public/pesqobjectosform.jsf',
'pesqObjectoForm%3Aidioma=PT&pesqObjectoForm%3Aempresa=CTT&pesqObjectoForm%3AobjectoId=RT039328389HK&pesqObjectoForm%3Asend=Pesquisar&pesqObjectoForm_SUBMIT=1&pesqObjectoForm%3A_link_hidden_=&pesqObjectoForm%3A_idcl=
');

//执行HTTP请求
function http_request($url,$method='GET',$data='',$cookie='',$refer=''){
$header='';
$body='';
$newcookie='';
if (preg_match('/^http:\/\/(.*?)(\/.*)$/',$url,$reg)){$host=$reg[1]; $path=$reg[2];}
else {outs("URL($url)格式非法!"); return;}
$http_host=$host;
if (preg_match('/^(.*):(\d+)$/', $host, $reg)) {$host=$reg[1]; $port=$reg[2];}
else $port=80;
$fp = fsockopen($host, $port, $errno, $errstr, 30);
if (!$fp) {
outs("$errstr ($errno)\n");
} else {
fputs($fp, "$method $path HTTP/1.1\r\n");
fputs($fp, "Host: $http_host\r\n");
if ($refer!='') fputs($fp, "Referer: $refer\r\n");
if ($cookie!='') fputs($fp, "Cookie: $cookie\r\n");
fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
fputs($fp, "Content-length: ".strlen($data)."\r\n");
fputs($fp, "Connection: close\r\n\r\n");
fputs($fp, $data . "\r\n\r\n");
$header_body=0;
while (!feof($fp)) {
$str=fgets($fp);
if ($header_body==1) $body.=$str;
else if ($str=="\r\n") $header_body=1;
else {
$header.=$str;
if (preg_match('|Set-Cookie: (\S+)=(\S+);|',$str,$reg)) $newcookie.=($newcookie==''?'':'; ').$reg[1].'='.$reg[2];
}
}
fclose($fp);
}
$GLOBALS['TRAFFIC']+=414+strlen($url)+strlen($data)+strlen($header)+strlen($body);
if (preg_match('/^Location: (\S+)\r\n/m',$header,$reg)) {
if (substr($reg[1],0,1)!='/'){
$path=substr($path,0,strrpos($path,'/')+1);
$path.=$reg[1];
} else $path=$reg[1];
if ($newcookie) $cookie=$newcookie;
return http_request('http://'.$http_host.$path,'GET','',$cookie,$url);
}
return array($body, $header, $newcookie);
}
?>
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
孤胆枪手怎么设置局域网啊、 我家小狗刚领来,没有名字,拜托大家起个名字。 护肤品代加工 水浒Q传跨服PK是怎么回事啊 新水浒Q传什么叫PK保护状态,上号不到一分钟就被打,求解 水浒Q传 为什么要pk有什么好处? 为什么贷款每次都审核失败 有谁能说一下手机贷审核不通过的原因吗?我都审核好多次了都不能通过... 贷款审核失败是什么原因 为什么贷款未通过审核 办学许可证很难办理吗 办学许可证在哪个部门办理 拖欠农民工工资多少钱可以报警立案? 经济案件立案的标准 民事纠纷多少钱才立案 微信上怎么才能转发别人发的视频到朋友圈里面?需要下载什么软件吗... 经济纠纷4000元可以起诉吗 微信转发不了别人的小视频怎么办 经济纠纷数目到多少法院立案 微信转发别人视频失败,和保存不了图片要怎么办 经济案件多少钱就可以立案 经济纠纷多少钱以上可以立案 信用卡怎么养?养卡有什么好处? 如何信用卡养卡??? 水在什么温度时开始结冰? 为什么蒸馏水结冰和矿泉水结冰的味道不一样 在相同的低温下,同质量的蒸馏水是冷水先结冰还是热水先结冰? 不是说蒸馏水不会结冰吗?为什么屈臣氏的蒸馏水结冰了? 在冬天 矿泉水和蒸馏水哪个更容易结冰 没有杂质的蒸馏水是不是不能结冰 油漆干在手上了杂洗掉.. 科比的鞋子尺码是多少啊? aj142码是多少cm 如何初步修炼法术 怎么修炼法力? 怎么样才能让自己有法力 - 信息提示 怎么样才能让自己有法力? 怎么修行怎么有法力 人类怎么拥有法术 - 信息提示 人类怎么才能修炼成仙的法术。 怎样才能有法力 佛教修行多久能得神通?应该如何修行? 如何修行能提高自身法力???永不退转???求大神帮助 拂尘怎么修炼才有法力 怎么样修行快?念啥? 华为P40手机怎么加表格行? 什么是动态ip,win10如何查询自己电脑的动态ip 用excel设计条码,实际和打印出来不同怎么办?