php实现异步数据调用的方法

浏览器和服务器之间只有一种面向无连接的HTTP协议进行通讯的,面向无连接的程序的特点是客户端请求服务端,服务端根据请求返回相应的程序,不能保持持久连接。这样就出现了一个问题,一个客户端的相应服务端可能执行1秒也有可能执行1分钟,这样浏览器就会一直处于等待状态,如果程序执行缓慢,用户可能就没耐心关掉了浏览器。
而有的时候我们不需要关心程序执行的结果,没有必要这样浪费时间和耐心等待,那我们就要想出办法让程序不收等待在后台静默执行。比如现在有一个场景,给1000个用户发送一封推荐邮件,用户输入或者导入邮件账号了提交服务器执行发送。

<?php
$count = count($emailarr);
for($i =0; $i < $count; $i++)
{
  sendmail();//发送邮件
}
?>

这段代码用户体验极差,也无法实际运用,首先发送这么多邮件会产生服务器运行超时,其实漫长的用户等待时间会让用户对系统产品怀疑和失去信心。但是用户不需要等待到1000封邮件都发送完毕了才提交发送成功,我们完全可以提交后台后直接给用户提示发送成功,然后让后台程序静默依次发送。
这个时候我们就需要“异步执行”技术来执行代码,异步执行的特点是后台静默执行,用户无需等待代码的执行结果,使用异步执行的好处:

  • 摆脱了应用程序对单个任务的依赖性
  • 提高了程序的执行效率
  • 提高了程序的扩展性
  • 在一定场景提高了用户体验
  • 因为PHP不支持多线程,使用异步调用的请求多个HTTP的方式达到了程序并行执行效果,但是注意的是请求的HTTP过多的话,会大大加大了系统的开销

PHP异步执行的常用方式
1. 客户端页面采用AJAX技术请求服务器
最简单的办法就是在返回给客户端的HTML代码中,嵌入AJAX调用,或者,嵌入一个img标签,src指向要执行的耗时脚本。这种方法最简单,也最快。服务器端不用做任何的调用。
但是缺点是,一般来说Ajax都应该在onLoad以后触发,也就是说,用户点开页面后,就关闭,那就不会触发我们的后台脚本了。
而使用img标签的话,这种方式不能称为严格意义上的异步执行。用户浏览器会长时间等待php脚本的执行完成,也就是用户浏览器的状态栏一直显示还在load。当然,还可以使用其他的类似原理的方法,比如script标签等等。
2. popen()函数
resource popen ( string command, string mode );
打开一个指向进程的管道,该进程由派生给定的 command 命令执行而产生。打开一个指向进程的管道,该进程由派生给定的 command 命令执行而产生。 所以可以通过调用它,但忽略它的输出。
pclose(popen("/home/xinchen/backend.php &", 'r'));
这个方法避免了第一个方法的缺点,并且也很快。但是问题是,这种方法不能通过HTTP协议请求另外的一个WebService,只能执行本地的脚本文件。并且只能单向打开,无法穿大量参数给被调用脚本。并且如果,访问量很高的时候,会产生大量的进程。如果使用到了外部资源,还要自己考虑竞争。
3. CURL扩展
CURL是一个强大的HTTP命令行工具,可以模拟POST/GET等HTTP请求,然后得到和提取数据,显示在"标准输出"(stdout)上面。

$ch = curl_init();
$curl_opt = array(CURLOPT_URL, 'http://www.example.com/backend.php',
       CURLOPT_RETURNTRANSFER, 1,
       CURLOPT_TIMEOUT, 1,);

curl_setopt_array($ch, $curl_opt);
curl_exec($ch);
curl_close($ch);

使用CURL需要设置CUROPT_TIMEOUT为1(最小为1,郁闷)。也就是说,客户端至少必须等待1秒钟。
4. fscokopen()函数
fsockopen是一个非常强大的函数,支持socket编程,可以使用fsockopen实现邮件发送等socket程序等等,使用fcockopen需要自己手动拼接出header部分。

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

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

以上就是为大家分享的4种PHP异步执行的常用方式,希望对大家的学习有所帮助。

(0)

相关推荐

  • PHP实现异步调用方法研究与分享

    这样就出现了一个问题,一个客户端的相应服务端可能执行1秒也有可能执行1分钟,这样浏览器就会一直处于等待状态,如果程序执行缓慢,用户可能就没耐心关掉了浏览器. 而有的时候我们不需要关心程序执行的结果,没有必要这样浪费时间和耐心等待,那我们就要想出办法让程序不收等待在后台静默执行. 比如现在有一个场景,给1000个用户发送一封推荐邮件,用户输入或者导入邮件账号了提交服务器执行发送. 复制代码 代码如下: <?php $count=count($emailarr); for($i=0;$i<$cou

  • 解决php使用异步调用获取数据时出现(错误c00ce56e导致此项操作无法完成)

    [详细错误]:由于出现错误 c00ce56e 而导致此项操作无法完成 [造成原因]:未指定输出编码格式. [解决办法]:句首加入header("content-type:text/html; charset=UTF-8");

  • PHP异步调用socket实现代码

    PHP异步调用实现方式 浏览器和服务器之间只一种面向无连接的HTTP协议进行通讯的,面向无连接的程序的特点是客户端请求服务端,服务端根据请求输出相应的程序,不能保持持久连接. 这样就出现了一个问题,一个客户端的相应服务端可能执行1秒也有可能执行1分钟,这样浏览器就会一直处于等待状态,如果程序执行缓慢,用户可能就没耐心关掉了浏览器. 而有的时候我们不需要关心程序执行的结果,没有必要这样浪费时间和耐心等待,那我们就要想出办法让程序不收等待在后台静默执行. 比如现在有一个场景,给1000个用户发送一封

  • php 异步调用方法实现示例

    php 异步调用方法 客户端与服务器端是通过HTTP协议进行连接通讯,客户端发起请求,服务器端接收到请求后执行处理,并返回处理结果. 有时服务器需要执行很耗时的操作,这个操作的结果并不需要返回给客户端.但因为php是同步执行的,所以客户端需要等待服务处理完才可以进行下一步. 因此对于耗时的操作适合异步执行,服务器接收到请求后,处理完客户端需要的数据就返回,再异步在服务器执行耗时的操作. 1.使用Ajax 与 img 标记 原理,服务器返回的html中插入Ajax 代码或 img 标记,img的s

  • php实现异步数据调用的方法

    浏览器和服务器之间只有一种面向无连接的HTTP协议进行通讯的,面向无连接的程序的特点是客户端请求服务端,服务端根据请求返回相应的程序,不能保持持久连接.这样就出现了一个问题,一个客户端的相应服务端可能执行1秒也有可能执行1分钟,这样浏览器就会一直处于等待状态,如果程序执行缓慢,用户可能就没耐心关掉了浏览器. 而有的时候我们不需要关心程序执行的结果,没有必要这样浪费时间和耐心等待,那我们就要想出办法让程序不收等待在后台静默执行.比如现在有一个场景,给1000个用户发送一封推荐邮件,用户输入或者导入

  • C++异步数据交换实现方法介绍

    异步数据交换,除了阻塞函数 send() 和 recv() 之外,Boost.MPI 还支持与成员函数 isend() 和 irecv() 的异步数据交换.名称以 i 开头,表示函数立即返回. 示例 47.7.使用 irecv() 异步接收数据 #include <boost/mpi.hpp> #include <boost/serialization/string.hpp> #include <string> #include <iostream> int

  • C#异步委托调用实例分析

    本文实例讲述了C#异步委托调用实现方法.分享给大家供大家参考.具体如下: static void Main(string[] args) { //委托异步 Action<string> showMessage = ShowMessage; IAsyncResult result = showMessage.BeginInvoke("测试异步委托",null, null); //那在异步线程未完成工作以前主线程将处于阻塞状态 //等到异步线程结束,主线程才能继续工作 show

  • 多种方式实现JS调用后台方法进行数据交互

    项目开发过程中很多地方都需要前端和后台的数据交互,几种典型常用的方法如利用控件的AutopostBack属性.Button提交表单等等.但这些都是有条件的,AutoPostBack具有实时性但会刷新页面,Button提交表单不能实现数据交互的实时性.当然说到前台与后台的数据交互更不能漏掉ajax,ajax实现前台与后台数据的异步交互,并且保证实时的.局部刷新.但有些数据不需要异步交互,例如当交互的数据是下一步执行的条件时,就必须要等到数据前台与后台数据交互完成后才能继续执行程序.所以对于掌握js

  • JS中async/await实现异步调用的方法

    async/await多个函数关联调用 async/await使得异步代码看起来像同步代码 async函数会隐式地返回一个promise,而promise的reosolve值就是函数return的值 Async/Await不需要写.then,不需要写匿名函数处理Promise的resolve值,也不需要定义多余的data变量,还避免了嵌套代码 async声明一个异步函数 await只能在async函数中使用,后面跟一个promise对象 所以在模拟异步调用函数时,函数体内返回promise as

  • Vue3异步数据加载组件suspense的使用方法

    目录 前言 创建组件 总结 前言 Vue3 增加了很多让人眼前一亮的特征,suspense 组件就是其中之一,对处理异步请求数据非常实用,本文通过简单的实例介绍其使用方法,如对其有兴趣,可以参阅官方文档. 通常组件在正确呈现之前需要执行某种异步请求是很常见的,通常是通过设计一种机制开发人员按照机制处理这个问题,有很多很好的方法实现这个需求. 例如,从一个 API 异步获取数据,并希望在获取响应数据解析完时显示一些信息,如 loading 效果,在Vue3中可以使用 suspense 组件来执行这

  • 详解Android的OkHttp包编写异步HTTP请求调用的方法

    OkHttp 除了支持常用的同步 HTTP 请求之外,还支持异步 HTTP 请求调用.在使用同步调用时,当前线程会被阻塞,直到 HTTP 请求完成.当同时发出多个 HTTP 请求时,同步调用的性能会比较差.这个时候通过异步调用可以提高整体的性能. 在通过 newCall 方法创建一个新的 Call 对象之后,不是通过 execute 方法来同步执行,而是通过 enqueue 方法来添加到执行队列中.在调用 enqueue 方法时需要提供一个 Callback 接口的实现.在 Callback 接

  • 关于layui的下拉搜索框异步加载数据的解决方法

    思路分析:当我使用layui默认的下拉搜索框的时候,layui会默认渲染出一个HTML结构,所以我把渲染出来的这个结果直接给复制出来,这样css的样式就不用从头到尾写一遍了, 前端代码(我用的是jsp): <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC &quo

  • 异步redis队列实现 数据入库的方法

    业务需求 app客户端向服务端接口发送来json 数据 每天 发一次 清空缓存后会再次发送 出问题之前业务逻辑: php 接口 首先将 json 转为数组 去重 在一张大表中插入不存在的数据 该用户已经存在 和新增的id 入另一种详情表 问题所在: 当用户因特殊情况清除缓存 导致app 发送json串 入库并发高 导致CPU 暴增到88% 并且居高不下 优化思路: 1.异步队列处理 2.redis 过滤(就是只处理当天第一次请求) 3.redis 辅助存储app名称(验证过后批量插入数据app名

  • Vue父组件和子组件之间数据传递和方法调用

    vue组件在通信中,无论是子组件向父组件传值还是父组件向子组件传值,他们都有一个共同点就是有中间介质,子向父的介质是自定义事件,父向子的介质是props中的属性. 父组件向子组件传值(子组件主动获取父组件的数据和方法) 父组件import引用子组件 使用子组件时在子组件上添加一个v-bind属性,并绑定上数据 在子组件中创建 props ,在props 中创建相同的属性名,用来接收数据 把接收到的数据在子组件中使用 子组件向父组件传值(父组件主动获取子组件的数据和方法) 子组件中需要发出该自定义

随机推荐