葡京网投哪个正规 > 新葡亰-编程 > 异步执行方法,PHP中实现异步调用多线程程序代码

原标题:异步执行方法,PHP中实现异步调用多线程程序代码

浏览次数:117 时间:2019-11-24

PHP 自身没有多线程的东西,但足以曲线的方法来作育出相像的功效,比如多进程的办法来完毕异步调用,仅限于命令情势。别的还应该有意气风发种更简便的主意可用于 Web 程序中,那便是用 fsockopen 来央浼八个 UPRADOL, 而无需等待再次来到,假如您在至极被号召的页面中做些专门的学业就相当于异步了。关键代码如下:复制代码 代码如下:照平时的情势就是:日志写完 -> 点提交按键 -> 日志插入到数据库 -> 发送邮件文告 -> 告知撰写者发表成功那么作者在点提交开关到见到成功唤醒之间只怕会等待很常时间,基本是在等邮件发送的长河,比方总是邮件服务十三分、或器缓慢或是订阅者太多。而实际上是无论邮件发送成功与否,保障日志保存成功基本可承当的,所以等待邮件发送的长河是非常不合算的,那么些进度可异步来实行,何况邮件发送的结果不太关爱或以日志情势记录备查。改革后的流水生产线就是:日志写完 -> 点提交按键 -> 日志插入到数据库 ---> 告知撰写者公布成功 └ 发送邮件公告 -> [笔录日志]写个实在的次序来测验一下,有多个文本,分别是 write.php 和 sendmail.php,在 sendmail.php 用 sleep 来模拟程序执行所使用时间。write.php,推行耗费时间 1 秒:复制代码 代码如下:'; echo 'call asyn_sendmail
'; asyn_sendmail.'
'; sendmail.php,试行耗时 10 秒:复制代码 代码如下:通过页面访谈write.php,页面输出:1272472697call asyn_sendmail1272472698况且在 C:/ 生成文件:1272472708从地点的结果能够看见 sendmail.php 最少花销 10 秒,但不会窒碍 write.php 继续往下实践,申明那后生可畏经过是异步的。

    $out .= "Connection: Closernrn";

末尾面有个数据库连接类,这里就不介绍了大大家可以百本站找相关的数据库连接mysql类哦
from:

sendmail.php

function strip_comment($address) {
$comment = "([^()]*)";

比方未来有八个情景,给1000个客户发送风姿洒脱封推荐邮件,客商输入只怕导入邮件账号了提交服务器实践发送。

list ($msec, $sec) = explode(" ", microtime());

这段代码顾客体验极差,也力不胜任实际选用,首首发送这么多邮件会发出服务器运营超时,其实漫长的客户等待时间会让顾客对系统产物猜疑和失去信心。不过客商无需等待到1000封邮件都发送实现了才提交发送成功,大家一同能够付出后台后一贯给客商提醒发送成功,然后让后台程序静默依次发送。

if ($this->log_file == "") {
return true;
}

客户体验:顾客等待->发送实现
爱人们就能够问,怎么贫乏发信环节?
OK,发信环节就在客商提交哀告的时候,把发信职分转给了二个独立管理发信的php程序管理了,当客户见到“发送达成”的时候实在信尚未发送完,当时,发信程序正在后台努力的办事着,生机勃勃封生机勃勃封的向外发送

function smtp_sockopen_relay() {
$this->log_write("Trying to " . $this->relay_host . ":" . $this->smtp_port . "n");

3.加强了前后相继的扩充性

if ($bcc != "") {
$TO = array_merge($TO, explode(",", $this->strip_comment($bcc)));
}

<?php
$domain="www.***.com";
$url="/system_mail.php";
$par="email=".implode(',',$emailarr)."&........";
$header = "POST $url HTTP/1.0rn";
$header .= "Content-Type: application/x-www-form-urlencodedrn";
$header .= "Content-Length: " . strlen($par) . "rnrn";
$fp = @fsockopen ($domain, 80, $errno, $errstr, 30);
fputs ($fp, $header . $par);
fclose($fp);

if (!($this->sock && $this->smtp_ok())) {
$this->log_write("Error: Cannot connenct to relay host " . $this->relay_host . "n");

好了,改成异步方式后,顾客提交音讯,能够立即赢得结果“发送实现”。信呢,会在后台湾学子机勃勃封大器晚成封的发送,直到发送完结。

$this->user = $user;

  1. popen()

if (!($this->sock && $this->smtp_ok())) {
$this->log_write("Warning: Cannot connect to mx host " . $host . "n");

$sqlserver/42852.htm target=_blank >count=count($emailarr);

function smtp_message($header, $body) {
fputs($this->sock, $header . "rn" . $body);

curl_exec($ch);

计算:通过挂号邮箱验证与本文邮件找回密码,大家领略发送邮件在网址开垦中的应用以致它的严重性,当然,未来也流行短信验证应用,那么些须要有关的短信接口对接就足以了。

 

$header .= "MIME-Version:1.0rn";

curl_close($ch);

fclose($this->sock);

1.解脱了应用程序对单个职务的依附

代码如下 复制代码
<p><strong>输入您注册的电子邮箱,找回密码:</strong></p>
<p><input type="text" class="input" name="email" id="email"><span id="chkmsg"></span></p>
<p><input type="button" class="btn" id="sub_btn" value="提 交"></p>

之所以可以透过调用它,但忽视它的出口。

if (!$this->smtp_putcmd("MAIL", "FROM:<" . $from . ">")) {
return $this->smtp_error("sending MAIL FROM command");
}

$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);

/* Private Functions */

                            CURLOPT_TIMEOUT, 1,);

本来别忘了在页面中加载jQuery库文件,有的同学时有时问作者说从www.111cn.net下载了demo怎么用持续,那五分四是jquery或许其余文件加载路线错了以致没加载必要的公文。
PHP

    $out .= "Host: www.example.comrn";

flock($fp, LOCK_EX);

 

var $smtp_port;

?>

3、系统经过该邮筒,从数据库中查找到该顾客新闻,并更新该客户的密码为叁个一时密码(比如:12345678卡塔尔国。

{

代码如下 复制代码
include_once("connect.php");//连接数据库

                            CURLOPT_RETURNTRANSFER, 1,

if (!$this->smtp_putcmd("", base64_encode($this->pass))) {
return $this->smtp_error("sending HELO command");
}
}

以此艺术防止了第一个法子的瑕疵,况兼也超级快。但是难点是,这种方法不能够通过HTTP公约需要别的的叁个WebService,只能施行本地的台本文件。而且只能单向展开,无法穿多量参数给被调用脚本。
同一时候只要,访问量异常高的时候,会发生大批量的经过。若是利用到了表面能源,还要本身思谋角逐。

function smtp_debug($message) {
if ($this->debug) {
echo $message . "
;";
}
}
}
?>

 代码如下

$this->time_out = 30; //is used in fsockopen()

 

if (!$this->smtp_message($header, $body)) {
return $this->smtp_error("sending message");
}

 代码如下

var $time_out;

while (!feof($fp)) {

HTML

  1. 使用fsockopen
    本条主意应该是最周到的,但是瑕疵是,你必要自个儿拼出HTTP的header部分。

return false;
;
}

    $out = "GET /backend.php / HTTP/1.1rn";

else
$cmd = $cmd . " " . $arg;
}

curl_setopt_array($ch, $curl_opt);

$this->sock = @ fsockopen($this->relay_host, $this->smtp_port, $errno, $errstr, $this->time_out);

2.增进了程序的实行效用

4、系统依附Jmail效用把该顾客的新闻发送到该客户的邮箱中(内容囊括:客户名、有时密码、提醒客户立刻修正一时密码的提示语卡塔尔。

pclose(popen("/home/xinchen/backend.php &", 'r'));

好了,那时候你的邮箱将会吸收意气风发封来自helloweba的密码找回寄邮资件,邮件内容中有二个U大切诺基L链接,点击该链接到www.111cn.net的reset.php来验证邮箱。

    fwrite($fp, $out);

$this->sock = @ fsockopen($host, $this->smtp_port, $errno, $errstr, $this->time_out);

以那时候大家就须要“异步奉行”技术来实施代码,异步实施的性状是后台静默实践,客户不需求等候代码的实行结果,使用异步推行的好处:

var $log_file;

经过试验,计算出来两种艺术,和大户人家share:
1. 最简便易行的方法,正是在回到给客商端的HTML代码中,嵌入AJAX调用,恐怕,嵌入贰个img标签,src指向要试行的耗费时间脚本。
这种方法最简易,也最快。服务器端不用做其余的调用。
唯独劣点是,平日的话Ajax都应当在onLoad现在触发,相当于说,客户点开页面后,就破产,那就不会触发大家的后台脚本了。
而使用img标签的话,这种措施不可能称之为严厉意义上的异步实施。客户浏览器会长期等待php脚本的推行到位,也等于顾客浏览器的场合栏一贯展现还在load。
道理当然是那样的,还足以使用其余的切近原理的秘籍,举例script标签等等。

function smtp($relay_host = "", $smtp_port = 25, $auth = false, $user, $pass) {
$this->debug = false;

  1. 使用CURL
    本条点子,设置CUROPT_TIMEOUT为1(最小为1,忧虑卡塔 尔(英语:State of Qatar)。约等于说,客户端起码必得等待1分钟。

return $sent;
}

4.在鲜明场景进步了客户体验

function sendmail($to, $from, $subject = "", $body = "", $mailtype, $cc = "", $bcc = "", $additional_headers = "") {
$mail_from = $this->get_address($this->strip_comment($from));

 $curl_opt = array(CURLOPT_URL, '',

return true;
}

  sendmail(.....);//发送邮件

$this->log_write("Error: Remote host returned "" . $response . ""n");

 代码如下

if (!$this->smtp_putcmd("RCPT", "TO:<" . $to . ">")) {
return $this->smtp_error("sending RCPT TO command");
}

}

class Smtp{

    echo "$errstr ($errno)<br />n";

return true;
}

}

$this->smtp_debug($response . "n");

<?php

代码如下 复制代码
<?php

if (!$fp) {

$header .= "From(www.111cn.net): $from<" . $from . ">rn";

echo ''发送达成';
?>
system_mail.php
<?php
ini_set("ignore_user_abort",true);
ignore_user_abort(true);//此处的代码要求php.ini开启相关的选项,保险php施行不超时的,不晓得,参谋作者的另意气风发篇文章“关闭浏览器后,php脚本会不会三番八次运营”
//获取email地址,发信,此处为发信代码
?>

if (!$this->smtp_putcmd("QUIT")) {
return $this->smtp_error("sending QUIT command");
}

echo fgets($fp, 128);

function smtp_sockopen_mx($address) {
$domain = ereg_replace("^.+@([^@]+)$", "1", $address);

for($i=0;$i<$count;$i )

if ($this->smtp_send($this->host_name, $mail_from, $rcpt_to, $header, $body)) {
$this->log_write("E-mail has been sent to <" . $rcpt_to . ">n");
} else {
$this->log_write("Error: Cannot send email to <" . $rcpt_to . ">n");

 

$this->log_write("Disconnected from remote hostn");
}

 代码如下

$token = stripslashes(trim($_GET['token']));
$email = stripslashes(trim($_GET['email']));
$sql = "select * from `t_user` where email='$email'";

}*/

$query = mysql_query($sql);
$row = mysql_fetch_array($query);
if($row){
$mt = md5($row['id'].$row['username'].$row['password']);
if($mt==$token){
if(time()-$row['getpasstime']>24*60*60){
$msg = '该链接已过期!';
}else{
//重新初始化密码...
$msg = '请重置密码,展现重新载入参数密码表单,<br/>这里只是演示,略过。';
}
}else{
$msg = '无效的链接';
}
}else{
$msg = '错误的链接!';
}
echo $msg;

} else {

var $debug;

resource popen ( string command, string mode );
//张开二个指向性进程的管道,该进程由派生给定的 command 命令实践而发生。展开二个照准进程的管道,该进度由派生给定的 command 命令推行而发出。

foreach ($MXHOSTS as $host) {
$this->log_write("Trying to " . $host . ":" . $this->smtp_port . "n");

$ch = curl_init();

$header .= "Message-ID: <" . date("YmdHis", $sec) . "." . ($msec * 1000000) . "." . $mail_from . ">rn";

5.因为PHP不扶持八线程,使用异步调用的号令五个HTTP的措施完毕了程序并行试行效果,不过注意的是必要的HTTP过多的话,会大大加大了系统的开支

$sent = false;
}

 代码如下

return $this->smtp_ok();
}

    fclose($fp);

如上使用的jQuery代码很有益于简单的到位了前边二个交互作用操作,倘令你有一定的jQuery幼功,那上面的代码总体上看,非常少解释。

    /*忽略试行结果

//发送邮件
function sendmail($time,$email,$url){
include_once("smtp.class.php");
$smtpserver = ""; //SMTP服务器,如smtp.163.com
$smtpserverport = 25; //SMTP服务器端口
$smtpusermail = ""; //SMTP服务器的顾客邮箱
$smtpuser = ""; //SMTP服务器的客户帐号
$smtppass = ""; //SMTP服务器的客户密码
$smtp = new Smtp($smtpserver, $smtpserverport, true, $smtpuser, $smtppass);
//那中间的三个true是象征使用身份验证,不然不利用地点验证.
$emailtype = "HTML"; //信件类型,文本:text;网页:HTML
$smtpemailto = $email;
$smtpemailfrom = $smtpusermail;
$emailsubject = "www.111cn.net - 找回密码";
$emailbody = "亲爱的".$email.":<br/>您在".$time."提交了找回密码央求。请点击上边包车型客车链接重新载入参数密码
(开关24钟头内有效卡塔 尔(英语:State of Qatar)。<br/><a href='".$url."'target='_blank'>".$url."</a>";
$rs = $smtp->sendmail($smtpemailto, $smtpemailfrom, $emailsubject, $emailbody, $emailtype);

1、顾客注册时索要提供贰个E-MAIL邮箱,指标就是用该邮筒找回密码。

$this->log_write("Connected to mx host " . $host . "n");

$header .= "Date: " . date("r") . "rn";

$this->log_write("Connected to relay host " . $this->relay_host . "n");

fputs($fp, $message);

$body = ereg_replace("(^|(rn))(.)", "1.3", $body);

安装思路

function smtp_ok() {
$response = str_replace("rn", "", fgets($this->sock, 512));

return true;
;
}

$this->relay_host = $relay_host;

var $relay_host;

return $address;
}

$TO = explode(",", $this->strip_comment($to));

continue;
}

function smtp_sockopen($address) {
if ($this->relay_host == "") {
return $this->smtp_sockopen_mx($address);
} else {
return $this->smtp_sockopen_relay();
}
}

$this->smtp_debug("> " . str_replace("rn", "n" . "> ", $header . "n> " . $body . "n> "));

$sql = "select id,username,password from `t_user` where `email`='$email'";
$query = mysql_query($sql);
$num = mysql_num_rows($query);
if($num==0){//该邮筒还没注册!
echo 'noreg';
exit;
}else{
$row = mysql_fetch_array($query);
$getpasstime = time();
$uid = $row['id'];
$token = md5($uid.$row['username'].$row['password']);//组合验证码
$url = "/demo/resetpass/reset.php?email=".$email."
&token=".$token;//构造URL
$time = date('Y-m-d H:i');
$result = sendmail($time,$email,$url);
if($result==1){//邮件发送成功
$msg = '系统已向您的邮箱发送了大器晚成封邮件<br/>请登陆到你的信箱及时重新恢复生机设置您的密码!';
//更新数据发送时间
mysql_query("update `t_user` set `getpasstime`='$getpasstime' where id='$uid '");
}else{
$msg = $result;
}
echo $msg;
}

/* Main Function */

/* Public Variables */

$this->log_write("Error: Cannot connect to any mx hosts (" . implode(", ", $MXHOSTS) . ")n");

if ($mailtype == "HTML") {
$header .= "Content-Type:text/htmlrn";
}

continue;
}

return $this->smtp_ok();
}

$sent = true;

return true;
}

$header .= "To: " . $to . "rn";

$sent = false;

$address = ereg_replace("^.*<(.+)>.*$", "1", $address);

2、当客商忘记密码或顾客名时,点击登陆页面包车型大巴“找回密码”超链接,张开表单,并输入注册用的E-MAIL邮箱,提交。

function smtp_eom() {
fputs($this->sock, "rn.rn");

var $pass;

if ($cc != "") {
$header .= "Cc: " . $cc . "rn";
}

$this->sock = false;
}

5、顾客用一时密码就能够登入。

if (!@ getmxrr($domain, $MXHOSTS)) {
$this->log_write("Error: Cannot resolve MX "" . $domain . ""n");

代码如下 复制代码
include_once("connect.php");//连接数据库

if (!$this->smtp_sockopen($rcpt_to)) {
$this->log_write("Error: Cannot send email to " . $rcpt_to . "n");

if (!ereg("^[23]", $response)) {
fputs($this->sock, "QUITrn");

return true;
}

function log_write($message) {
$this->smtp_debug($message);

var $auth;

咱俩在找回密码的页面上放置一个渴求客户输入注册时所用的信箱,然后交由前台js来拍卖相互。

if (!$this->smtp_putcmd("DATA")) {
return $this->smtp_error("sending DATA command");
}

$this->log_write("Error: " . $errstr . " (" . $errno . ")n");

$this->smtp_debug("> " . $cmd . "n");

reset.php首先选取参数email和token,然后遵照email查询数据表t_user中是或不是留存该Email,假诺存在则得到该顾客的信息,并且和sendmail.php中的token组合措施相符创设token值,然后与url传过来的token进行自查自纠,假设当前光阴与发送邮件时的时光间距超过24钟头的,则提醒“该链接已过期!”,反之,则证实链接有效,而且调转到重新载入参数密码页面,最后就是顾客自身安装新密码了。

function smtp_error($string) {
$this->log_write("Error: Error occurred while " . $string . ".n");

if (!@ file_exists($this->log_file) || !($fp = @ fopen($this->log_file, "a"))) {
$this->smtp_debug("Warning: Cannot open log file "" . $this->log_file . ""n");

if ($cc != "") {
$TO = array_merge($TO, explode(",", $this->strip_comment($cc)));
}

$header .= "X-Mailer:By Redhat (PHP/" . phpversion() . ")rn";

$this->log_write("Error: " . $errstr . " (" . $errno . ")n");

提及底,附上数据表t_user结构:

fputs($this->sock, $cmd . "rn");

jQuery

代码如下 复制代码
$(function(){
$("#sub_btn").click(function(){
var email = $("#email").val();
var preg = /^w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*/; //匹配Email
if(email=='' || !preg.test(email)){
$("#chkmsg").html("请填入精确的邮箱!");
}else{
$("#sub_btn").attr("disabled","disabled").val('提交中..').css("cursor","default");
$.post("sendmail.php",{mail:email},function(msg){
if(msg=="noreg"){
$("#chkmsg").html("该邮筒还未有注册!");
$("#sub_btn").removeAttr("disabled").val('提 交').css("cursor","pointer");
}else{
$(".demo").html("<h3>"+msg+"</h3>");
}
});
}
});
})

$header .= "Subject: " . $subject . "rn";

return $rs;
}

function get_address($address) {
$address = ereg_replace("([ trn])+", "", $address);

if (!$this->smtp_eom()) {
return $this->smtp_error("sending <CR><LF>.<CR><LF> [EOM]");
}

while (ereg($comment, $address)) {
$address = ereg_replace($comment, "", $address);
}

$header .= $additional_headers;

return true;
}

/* Constractor */

$this->host_name = "localhost"; //is used in HELO command
$this->log_file = "";

return false;
}

fgets($this->sock, 512);

return $address;
}

$email = stripslashes(trim($_POST['mail']));

当顾客输入完邮箱并点击提交后,jQuery先验证邮箱格式是还是不是准确,即使不易则透过向后台sendmail.php发送Ajax央浼,sendmail.php担任验证邮箱是或不是留存和出殡和下葬邮件,并会回去相应的管理结果给前台页面,请看jQuery代码:

var $user;

var $host_name;

smtp.class.php类文件

/* Private Variables */
var $sock;

function smtp_putcmd($cmd, $arg = "") {
if ($arg != "") {
if ($cmd == "")
$cmd = $arg;

return false;
}

$this->auth = $auth; //auth

$this->smtp_debug(". [EOM]n");

return false;
}

代码如下 复制代码
CREATE TABLE `t_user` (
`id` int(11) NOT NULL auto_increment,
`username` varchar(30) NOT NULL,
`password` varchar(32) NOT NULL,
`email` varchar(50) NOT NULL,
`getpasstime` int(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

return false;
}

function smtp_send($helo, $from, $to, $header, $body = "") {
if (!$this->smtp_putcmd("HELO", $helo)) {
return $this->smtp_error("sending HELO command");
}
// auth
if ($this->auth) {
if (!$this->smtp_putcmd("AUTH LOGIN", base64_encode($this->user))) {
return $this->smtp_error("sending HELO command");
}

foreach ($TO as $rcpt_to) {
$rcpt_to = $this->get_address($rcpt_to);

$message = date("M d H:i:s ") . get_current_user() . "[" . getmypid() . "]: " . $message;

sendmail.php须要验证Email是不是存在系统客商表中,要是有,则读取顾客音讯,将顾客id、客商名和密码受惊而醒md5加密生成八个特意的字符串作为找回密码的验证码,然后构造UXC60L。同期大家为了垄断U昂科雷L链接的时效性,将记录客商提交找回密码动作的操作时间,最后调用邮件发送类发送邮件到顾客邮箱,发送邮件类smtp.class.php已经打包好,请下载。

fclose($fp);

$this->smtp_port = $smtp_port;

return false;
}

$this->pass = $pass;

本文由葡京网投哪个正规发布于新葡亰-编程,转载请注明出处:异步执行方法,PHP中实现异步调用多线程程序代码

关键词:

上一篇:启用disable_functions提高安全,disabled函数禁用的解决方法_php技巧_脚本之家

下一篇:PHP中使用AES加密算法加密数据的例子,php中AES加密解密的例子小结_php实例_脚本之家葡京网投哪个正规: