• 有关PHP后台任务的想法


      最近在项目中碰到这样一个需求,PHP执行一些操作后,需要发送通知邮件,原来的代码如下:

    $result_array = array('handle_action'=>$handle_action,
            'result'=> YesOrNo::YES,
            'message'=>'单据审批通过'
    );
                    
    echo json_encode($result_array);
    //处理完毕,邮件通知下一位处理人
    $this->sendmailtonextaudit($bean_id, $bean_code, $status, $handle_action, $handle_opinion);
    exit();   

      但是发送邮件的这步操作$this->sendmailtonextaudit()大约需要6秒多,这样前台就必须等待了,为了实现前台无需等待的需求,考虑将发送邮件的代码放到后台去执行,处理代码如下:

    $result_array = array('handle_action'=>$handle_action,
        'result'=> YesOrNo::YES,
        'message'=>'单据审批通过'
    );
                    
    while(ob_get_level())
    {
        ob_end_clean();//清除之前开启了的缓冲区
    }
    header('HTTP/1.1 200 Ok');
    header('Connection:close');//告诉浏览器,连接关闭了,这样浏览器就不用等待服务器的响应
    header("Content-Encoding: none");
    ignore_user_abort(true);
    ob_start(); 
    echo json_encode($result_array);
    $size = ob_get_length();
    header("Content-Length:$size");//告诉浏览器这个网页文件的长度,只有这样浏览器才会接收到相应长度的信息后中断连接
                    
    ob_end_flush();//输出当前缓冲
    flush();//输出PHP缓冲
                    
    sleep(30);//休眠PHP,让php把前面的输出作完
                    
    set_time_limit(0);//不受时间限制
    //处理完毕,邮件通知下一位处理人
    $this->sendmailtonextaudit($bean_id, $bean_code, $status, $handle_action, $handle_opinion);
    exit();

      相应前台代码(是用ajax调用的):

    $.ajax({
        type:"POST",
        url:"/public/common/ajaxaudittrade",
        data:params,
        success: function(res){
            var obj = eval( "(" + res + ")" );
            alert(obj.message);//这一步可以很快返回
            toUrl('/trade/approved/index');
         }
    });

      以上颜色加深的alert能够很快执行(不到1秒),这说明后台处理是正确的,sleep之前的内容已输出。现在问题是,后面的toUrl不会马上执行,必须等到sleep之后的代码执行完毕,才能执行toUrl。看到这里,我原先以为是前后台连接没有断开,浏览器一直在等待服务器(Apache)的响应,后来发现不是这样的。这里的连接确实已断开,之所以toUrl一直在等待,并不是它没被执行,而是执行了在等待响应而已,说的有点迷糊了吧,下面来解释下。

      web访问中,每一个会话(session)对应一个进程,上面说到的sleep后面要执行的代码和toUrl请求执行的代码,是在同一个会话下,所以它们属于同一个进程。这就导致sleep不执行完,toUrl不会执行。所以现在考虑让sleep后面的代码启用新的进程来执行,这就像“守护进程”一样,要做到:

      1.让新进程摆脱原会话的控制;

      2.让新进程摆脱原进程组的控制;

      3.让新进程摆脱原控制终端的控制;

      关于PHP中“守护进程”的用法,正在摸索中,弄明白后,会补充到这个帖子中。

      PS:以上纯属个人见解,如有不对,请猛喷之。

  • 相关阅读:
    Tkinter之布局管理pack
    Python smtplib,email
    PyAutoGUI (2) 屏幕处理和弹框,输入中文
    键鼠操作自动化库--PyAutoGUI模块(1)
    python----->>删除超过固定天数的日志
    Transformer再下一城!Swin-Unet:首个纯Transformer的医学图像分割网络
    西门子S7-1200 PLC 水箱水位控制程序案例
    【开源】Transformer 在CV领域全面开花:新出跟踪、分割、配准等总结
    Google发布语义分割新数据集!顺带开发个模型屠榜,已被CVPR2021接收
    YOLOv5算什么,这个才是最强!---PP-YOLOv2
  • 原文地址:https://www.cnblogs.com/phpCHAIN/p/3483565.html
Copyright © 2020-2023  润新知