Yii 框架中的 PHP 异步方法调用

2024-02-11

Question

我想知道是否可以在操作呈现视图时从 Yii 控制器方法之一异步调用该方法,让该方法完成长时间运行的操作。我想做类似下面的代码的事情,并且不需要返回结果my_long_running_func.

public function actionCreate() {
    $model = new Vacancies;
    if (isset($_POST['Vacancies'])) {
        $model->setAttributes($_POST['Vacancies']);
        $model->save();
        //I wish :)
        call_user_func_async('my_long_running_func',$model);
    }
    $this->render('create', array( 'model' => $model));
}

Problem

我正在尝试在 Yii 中编写一个控制器操作,用于发布职位空缺并通知对该帖子感兴趣的订阅者。问题是执行通知查询需要很长时间。

现在,我正在寻找一种异步运行查询的方法,以便发布者在尽可能短的时间内看到他的响应,同时查询以类似于 C# 委托或事件的方式在后台运行。

我用谷歌搜索到的解决方案执行异步请求在控制器操作过程中,但我想做的就是异步运行控制器的方法,并且操作必须wait直到要求)已完成。

尝试过

我尝试了以下方法,但是对于我的1500个用户左右的测试数据,查询仍然很慢。

  • Yii 活动记录

    if ($vacancy->save()) {                
        if($vacancy->is_active == 1) {
            $url = Yii::app()->createUrl('vacancies/view',array('id'=>$model->id));
            $trainees = YumUser::getUsersByRole('Trainees');
            if($trainees!=null) {
                foreach($trainees as $trainee){
                    $message = new YumMessage;
                    $message->from_user_id = Yii::app()->user->id;
                    $message->title = 'Vacancy Notification: '.date('M j, Y');
                    $message->message = "A new vacancy has been posted at <a href='{$url}'>{$url}</a>.";
                    $message->to_user_id = $trainee->id;
                    $message->save();                
                }
            }
        }    
    }
    
  • Yii 数据访问对象

    if ($vacancy->save()) {        
        if($vacancy->is_active == 1) {
            $url = Yii::app()->createAbsoluteUrl('vacancies/view',array('id'=>$model->id));
            $trainee_ids=Yii::app()->db->createCommand()->select('user_id')->from('trainee')->queryColumn();
            $fid=Yii::app()->user->id;
            $msg="A new vacancy has been posted at <a href='{$url}'>{$url}</a>.";
            $ts = time();
            $tt = 'Vacancy Notification: '.date('M j, Y');
            if($trainee_ids!=null) {
                foreach($trainee_ids as $trainee_id){
                    Yii::app()->db->createCommand()
                      ->insert('message',array('timestamp'=>$ts,'from_user_id'=>$fid,'to_user_id'=>$tid,'title'=>$tt,'message'=>$msg));
                }
            }
        }
    }
    
  • 准备好的报表

    if ($vacancy->save()) {                
        if($vacancy->is_active == 1) {
            $url = Yii::app()->createUrl('vacancies/view',array('id'=>$model->id));                    
            $trainee_ids=Yii::app()->db->createCommand()->select('user_id')->from('trainee')->queryColumn();
            $fu=Yii::app()->user->id;
            $msg="A new vacancy has been posted at <a href='{$url}'>{$url}</a>.";
            $ts = time();
            $tt = 'Vacancy Notification: '.date('M j, Y');
            $sql="INSERT INTO message (timestamp,from_user_id,title,message,to_user_id) VALUES (:ts,:fu,:tt,:msg,:tu)";
            if($trainee_ids!=null) {
                foreach($trainee_ids as $trainee_id){
    
                    $command=Yii::app()->db->createCommand($sql);
                    $command->bindParam(":ts",$ts,PDO::PARAM_INT);
                    $command->bindParam(":fu",$fu,PDO::PARAM_INT);
                    $command->bindParam(":tt",$tt,PDO::PARAM_STR);
                    $command->bindParam(":msg",$msg,PDO::PARAM_STR);
                    $command->bindParam(":tu",$trainee_id,PDO::PARAM_INT);
    
                    $command->execute();
    
                }
            }
        }
    }
    

Research

我还检查了以下网站(我只允许发布两个链接),但它们要么需要等待请求完成的操作,要么需要curl(我在部署服务器上无权访问)或需要一个外部库。我希望有一个本地 PHP 实现。

  • PHP模拟多线程
  • PHP中的多线程
  • 异步 PHP 调用? https://stackoverflow.com/questions/124462/asynchronous-php-calls
  • PHP 中的异步处理 http://css.dzone.com/articles/asynchronous-processing-php

Edit

通过以这种方式重写查询(将用户循环移至数据库层),我能够大大减少响应时间:

public function actionCreate() {
    $user=YumUser::model()->findByPk(Yii::app()->user->id);
    $model = new Vacancies;
    $model->corporate_id=$user->professional->institution->corporate->id;
    $model->date_posted=date('Y-m-d');
    $model->last_modified=date('Y-m-d H:i:s');

    if (isset($_POST['Vacancies'])) {
        $model->setAttributes($_POST['Vacancies']);
        if ($model->save()) {                
            if($model->is_active == 1) {
                $url = Yii::app()->createAbsoluteUrl('vacancies/view',array('id'=>$model->id));                    
                $fu=Yii::app()->user->id;
                $msg="A new vacancy has been posted at <a href='{$url}'>{$url}</a>.";
                $ts = time();
                $tt = 'New Vacancy: '.$model->title;
                $sql='INSERT INTO message (timestamp,from_user_id,title,message,to_user_id) SELECT :ts,:fu,:tt,:msg,t.user_id FROM trainee t';
                Yii::app()->db->createCommand($sql)->execute(array(':ts'=>$ts,':fu'=>$fu,':tt'=>$tt,':msg'=>$msg));
            }                
            if (Yii::app()->getRequest()->getIsAjaxRequest())
                Yii::app()->end();
            else
                $this->redirect(array('view', 'id' => $model->id));
        }
    }
    $this->render('create', array( 'model' => $model));
}

尽管如此,如果有人可以发布一种异步调用函数的方法,那就太好了。


通常,此类问题的解决方案是在系统中集成消息总线。您可以考虑类似的产品豆茎 http://kr.github.io/beanstalkd/。这需要在您的服务器上安装软件。 我想这个建议将被称为“使用外部库”。

如果您可以访问部署服务器并且可以添加 cronjob (或者系统管理员可以),您可以考虑使用 cronjob 对脚本进行 php-cli 调用,该脚本从数据库中的作业队列读取作业,该队列由控制器填充方法。

如果您无法在正在运行的服务器上安装软件,您可以考虑使用 SAAS 解决方案,例如Iron.io http://www.iron.io/为您托管总线功能。 Iron.io 正在使用所谓的推送队列。通过推送队列,消息总线主动向注册的侦听器执行带有消息内容的请求(推送)。这可能会起作用,因为它不需要您执行卷曲请求。

如果以上都不可行,那么您就束手无策了。另一篇与该主题非常相关的帖子:可扩展、延迟的 PHP 处理 https://stackoverflow.com/questions/3115191/scalable-delayed-php-processing

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Yii 框架中的 PHP 异步方法调用 的相关文章

  • 从twitter api实体参数php获取图像url

    我正在尝试通过实体参数使用 php 获取并显示在推文中发布的图像 我的 url 中有 include entities 可以看到返回的 json 中的实体 在我的 foreach 循环中 我正在执行以下操作 foreach results
  • Ubuntu 18.04升级后php7.2-curl无法安装

    今天从 16 04 升级到 18 04do release upgrade d 在升级过程中 我被告知一些软件包将被删除 其中包括 删除 libperl5 22 lxc common perl modules 5 22 php imagic
  • 本地数据库缓存的最佳实践?

    我正在开发一个应用程序 该应用程序的部分内容依赖于 MySQL 数据库 在某些情况下 应用程序将在互联网连接 UMTS 有限的环境中运行 特别是延迟较高的环境 应用程序的用户能够登录 并且应用程序用户界面的大部分内容都是从 MySQL 数据
  • 基本表创建 fpdf

    我找不到使用 fpdf 制作表格并从 mysql 数据库获取数据的合适教程 我只是想知道如何创建一个 我在网上尝试示例时遇到了很多错误 例如 我有 名字 中间名 姓氏 年龄 和 电子邮件 列 如何使用 fpdf 创建表格并回显数据库中的条目
  • PHP 如果不存在,则从字符串中删除 ','

    我正在运行这段代码 stmt pdo conn gt prepare SELECT from admin where support emails support emails and logged logged and disabled
  • Facebook 中用户的时区是如何编码的

    我需要检查用户的时区 但我找不到它的真正定义 参考API http developers facebook com docs reference api user says 用户的时区与 UTC 的偏移量 现在在维基百科上这些是可能的时区
  • 如何读取 XML 文件并从中获取值以在 PHP 编码的 HTML 页面中显示

    我有一个 XML 文件 其中有一些重复的标签 其中包含不同的值 我需要获取这些值并显示在我的网页中 请帮助我得到这个 如果您使用 PHP5 可以查看 SimpleXML 您可以在这里找到介绍教程 http www w3schools com
  • Opencart最低下单价不包括一类

    我正在使用 opencart 并成功为所有交易添加了最低订单价格 这是我使用的代码 div div div class warning Minimum 10 Euro to checkout div 现在我想从中排除一个类别 以便可以购买该
  • 根据通过 AJAX 请求的用户输入重绘 google 图表

    我有一个谷歌图表从我的数据库中提取数据 它可以按我想要的方式工作 根据 URL 中的 get 请求 它从所选表中提取数据 我想根据下拉菜单中选定的表通过 ajax 更新此图表 我无法突破的部分是通过 ajax 获取数据响应 我认为下面的代码
  • 在 Apache 服务器上将特定的 .htm 页面处理为 .php [重复]

    这个问题在这里已经有答案了 我正在为 Apache 服务器编程 并且只需要将一个特定的 html 页面 例如 first htm 作为 PHP 脚本进行处理 可以设置吗 SetHandler http httpd apache org do
  • #1045 - 用户“root”@“localhost”的访问被拒绝(使用密码:YES)

    这可能看起来多余 但我无法找到正确的解决方案 我无法使用 mysql 控制台登录 mysql 它要求输入密码 但我不知道我实际输入的内容 有办法获取密码或更改密码吗 这就是我的 config inc 的样子 当我尝试打开 phpmyadmi
  • 从数据库 MYSQL 和 Codeigniter 获取信息

    如果你们需要其他信息 上一个问题就在这里 从数据库中获取信息 https stackoverflow com questions 13336744 fetching information from the database 另一个更新 尽
  • laravel 5.4 在请求验证之前修改数据[关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我有我的自定义请求 它扩展了 Backpack CrudController 现在我想重写 ValidatesWhenResolv
  • PHP 时间间隔

    我正在寻找一个看起来应该非常简单的解决方案 但似乎我不能在这里找到任何好的答案 而且我自己似乎无法让它发挥作用 我正在寻找的是设置开始时间 结束时间 然后迭代给定时间间隔之间的一组时间 例如 上午 9 00 下午 5 00 是开始时间 这些
  • 隐藏产品价格和添加到购物车按钮,但不隐藏 WooCommerce 中未注册用户的变体

    在我的 WooCommerce 商店中 我想隐藏价格 直到客户登录为止 我有以下代码可以实现这一点 add action init hide price function hide price if is user logged in re
  • Laravel - 覆盖模型 ID

    我正在开发电子书管理系统 我使用 UUID 而不是自动递增整数主键 它工作得很好 protected static function boot parent boot static creating function model model
  • 如何使用 PHP 获取列中的所有值?

    我一直在到处寻找这个问题 但仍然找不到解决方案 如何从 mySQL 列中获取所有值并将它们存储在数组中 例如 表名称 客户 列名称 ID 名称 行数 5 我想获取此表中所有 5 个名称的数组 我该如何去做呢 我正在使用 PHP 我试图 SE
  • 让 Prometheus 发送 SQL 查询

    我正在尝试使用普罗米修斯 https prometheus io 监视我的 MySQL 数据库 但似乎找不到添加 SQL 查询的区域 例如 我想运行一个返回值的 SQL 查询 然后将该值添加到图表中 发送警报 有没有办法让 Promethe
  • 在 ASP.NET 中将事件冒泡为父级

    我已经说过 ASP NET 中的层次结构 page user control 1 user control 2 control 3 我想要做的是 当控件 3 它可以是任何类型的控件 我一般都想这样做 让用户用它做一些触发回发的事情时 它会向
  • 通过将行旋转为动态数量的列来在 MySQL 中创建摘要视图

    我在 MySQL 中有一个表 其中包含以下字段 id company name year state 同一客户和年份有多行 以下是数据示例 id company name year state 1 companyA 2008 1 2 com

随机推荐

  • 将 NSArray 转换为 NSMutableArray Swift

    我正在尝试转换self assets NSArray to NSMutableArray并将其添加到picker selectedAssets这是一个NSMutableArray 这段代码在 swift 中会是什么样子 Objective
  • 如何强制用户下载图像(如下载 pdf)?

    因此 我编写了一个图像库 其中包含下载原始图像的选项 默认情况下 它显示图像的调整大小版本 我很想知道如何 下面的代码将强制用户保存 pdf 而不是使用浏览器查看它 我希望通过将单击操作与 jQuery 绑定来实现图像 jpg gif pn
  • Material-UI [v0.x] 悬停样式上的 RaisingButton

    我想更改悬停时 Material UI RaisingButton 的样式 但似乎没有特定的选项可以做到这一点 因为悬停时发生的情况是由材料设计指南定义的 然而 当鼠标悬停在按钮上时 有什么方法可以更改按钮的样式 主要是颜色和背景颜色 吗
  • C# 中 itextsharp 中的文本格式设置

    我正在尝试使用我的 C 软件创建 pdf 文件 我在用itextsharp库来创建客户账单收据 但是我无法格式化文本 我们如何格式化pdf文件中的文本 仅新行字符 n似乎正在工作 我们如何使用制表符格式化文本 附件是 pdf 文件中文本的屏
  • 如何在 Unity 中创建一个可以显示由许多小图像组成的纹理的着色器

    所以我想做的是从 SQL 表加载卫星图像并将它们包裹在一个球体周围以创建一个地球仪 我知道我已经加载了所涵盖的图像 我只是不确定如何使我的着色器以正确的方向显示图像 我去了 Unity 论坛并查看了这段代码 https docs unity
  • 从Python中的函数返回错误字符串

    我在 Python 中有一个类函数 它要么返回成功 要么返回失败 但如果失败 我希望它发回特定的错误字符串 我想到了 3 种方法 将变量 error msg 传递给最初设置为 None 的函数 如果出现错误 它将设置为错误字符串 例如 if
  • 如何使用 C# Windows 应用程序将图像从 byte[] 写入 MS WORD

    我尝试从以下位置写入数据FileStream StreamWriter到一个word文件 当数据是文本格式时它工作正常 使用StreamWriter 但是当我尝试同样的方法时Binarywriter 用于将图像写入Word文档 它错误地写入
  • 读取表变量的查询可以在 SQL Server 2008 中生成并行执行计划吗?

    首先 从BOL http msdn microsoft com en us library ms175010 aspx 修改的查询table变量不生成并行查询执行计划 当非常大时 性能可能会受到影响table变量或复杂查询中的表变量被修改
  • 使用 VM 参数导出 jar

    我已经使用 Eclipse 编写了一个 Java 应用程序 该应用程序使用 SWT 作为 UI 看运行 jar 时出现 SWT 异常 线程 main 中出现异常 org eclipse swt SWTException 线程访问无效 htt
  • 使用 Flask 时 PyCUDA 上下文错误

    我正在使用 PyCUDA 来实现 smooth local affine 如图所示here https github com LouieYang deep photo styletransfer tf blob master smooth
  • 如何声明一个字节数组包含非ascii字符而不在python 3中转义

    这是我用python2写的一个例子 usr bin env python coding utf 8 from future import print function import sys struct def pack s list re
  • 如何修改ActiveXObject JS构造函数?

    我需要包装一个 IE ajax 请求以在发生时通知我 即我需要知道何时调用 open var xhr new ActiveXObject Microsoft XMLHTTP 做到这一点的唯一方法 我认为 是实现 ActiveXObject
  • 多个 ajax 调用的 jQuery 回调

    我想在单击事件中进行三个 ajax 调用 每个 ajax 调用都会执行不同的操作并返回最终回调所需的数据 这些调用本身并不相互依赖 它们可以同时进行 但是我希望在所有三个调用完成后进行最终回调 button click function f
  • 使用 Stream 比较两个集合 - anyMatch

    我想比较 a 中是否有任何对象list2存在于一个list1 我可以迭代两个列表并使用比较所有元素 contains 但我想知道是否没有更有效的方法 我发现this https stackoverflow com questions 225
  • 在 oninvalid 消息中创建换行符

    我想在 oninvalid 弹出消息中创建换行符 以便我可以在不同行上列出错误消息的多个要求 这是我试图创建的示例代码
  • R networkD3:单击操作显示节点数据帧的信息

    我有这个代码 library networkD3 Load data data MisLinks data MisNodes new nodes lt MisNodes new nodes var1 lt runif nrow MisNod
  • Android:如何在 Android 应用程序中显示谷歌地图?

    我已经构建了一个应用程序 可以为我进行一些坐标计算 它工作得很好 它也从我构建的数据库中检索点 我现在想做的是当按下菜单按钮时显示地图 我做了一个教程 只是一个地图显示 这就是它运行时所做的一切 但是当我尝试将我所做的事情合并到我的应用程序
  • UTF-8 中的值在 JSON 中被编码为 NULL

    我有一组关键字通过 JSON 从数据库 编码的 UTF 8 传递 其中一些可能具有特殊字符 如 等 这用作自动完成器的一部分 例子 array Coffee Cappuccino Caf 我应该补充一点 来自数据库的数组将是 array C
  • android:webview 未使用自定义 WebViewClient 加载 javascript

    我有一个非常基本的WebView这一直有效 直到我尝试添加自定义webViewClient它停止处理 JavaScript 的地方 难道我做错了什么 是否有另一种方法可以摆脱 WebView 中的地址栏和菜单选项 browser WebVi
  • Yii 框架中的 PHP 异步方法调用

    Question 我想知道是否可以在操作呈现视图时从 Yii 控制器方法之一异步调用该方法 让该方法完成长时间运行的操作 我想做类似下面的代码的事情 并且不需要返回结果my long running func public function