php中事件的含义

2023-11-30

我也知道php和nodejs,在javascript中我们有异步编程,所以我理解其中事件的含义。但是我看到了Yii 和 Zend 2 中的事件也使用它们,但我无法理解它的含义,它在 php 中如何工作以及它到底有什么作用?


首先,PHP中没有事件

事件是回调函数及其名称的抽象。 通常,我们将它们定义为$eventName => $listener, where $listener是一个回调函数$eventName

事件和常规回调函数有什么区别?

再次强调 - 要记住的核心点是事件是回调函数。而已。

它们之间唯一的区别是我们如何调用它们。

An event is defined on bootstrap step with its required arguments, but invoked on demand without arguments. While the callback function is invoked with arguments and only

考虑这个例子,

<?php

$eventManager = new EventManager();
$eventManager->attach('my_event', function(){

   print_r(func_get_args());

}, array('foo', 'bar'));

因为我们刚刚定义了一个事件,所以我们会调用,

$eventManager->trigger('my_event');

这将输出:Array([0] => [foo], [1] => [bar]

这与 JavaScript 有关!

由于我们大多数人都熟悉 JavaScript 事件驱动架构,因此无需提及其常见用法的示例:

var a = document.getElementsByTagName('a')[0];
a.onclick = function(event) { // <-- We define an event with the event argument
   event.preventDefault();
   alert('A element was clicked');
}

a.click(); // <-- but we invoke it without arguments

// or If you want a Jquery
$("a").click(function(event){
   event.preventDefault();
   alert('A element was clicked');
});

$("a").click();

由于在 PHP 中我们没有这种事件驱动的性质,因此我们可以将其替换为我们自己的管理事件的类并充分利用它。

为什么要使用它们?

虽然事件让很多人感到困惑,但它们非常有用。

想象一下你有一个内容管理系统(CMS),您的用户可以决定如何处理404错误。说,他们可以处理

1)显示空白页
2) 重定向至/
3) 显示自定义消息

如果没有事件,你就必须这样做,比如

if ($router->isMatched($request)){

    //do dispatch etc

} else {

   // Here you start handling 404 errors

   switch($config->read('404_way_handle')){

       case 'show_blank':
          die();
       break;

       case 'show_msg':
          echo 'Some custom message';
       break;

       case 'redirect':
          // do redirect
       break;
   }
}

通过事件,您可以简化可读性并使代码更易于维护:

if ($router->isMatched($request)){
   // do dispatch
} else {

   $eventManager->trigger('404_handler');
}

while 404_handler本身看起来像

  $eventManager->attach('404_handler', function(){

       switch($config->read('404_way_handle')){

           case 'show_blank':
              die();
           break;

           case 'show_msg':
              echo 'Some custom message';
           break;

           case 'redirect':
              // do redirect
           break;
       }

  }, $config);


那么让我们来分解一下

1)事件提高了可读性,这对未来很有好处

2) 活动确实遵守单一职责原则,因为你可以简单地注入$eventManager到需要它的类,而回调函数可能会破坏它或者可能引入一个全局状态也是如此(这对单元测试不利)。

3)有不同类型的逻辑 - 模板逻辑、业务逻辑、错误处理程序逻辑、数据访问逻辑等。 事件简化通过将业务(或其他类型)逻辑与其应用程序逻辑解耦配置逻辑,以便您最终获得清晰的应用程序逻辑。

你可以看这个lecture如果您想知道它们在 Zend Framework 2 中如何工作(即使您不熟悉 Zend Framework 2,也请观看)

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

php中事件的含义 的相关文章

随机推荐

  • 从Google Apps脚本中的类似csv文件读取数据

    我有一个 Windows 脚本文件 尽管不是 Google Apps 脚本 它将数据输出到文本文件 该文件包含以逗号分隔的数字 类似于 CSV 文件 但以编程方式创建 我可以在 Excel 中将其作为 CSV 文件打开 该文件存储在我的 G
  • querySelectorAll - 我可以在选择器中添加“:after”吗?

    我可以在 JavaScript 中执行此操作吗 var Dim Back document querySelectorAll s1 after for var i 0 i lt Dim Back length i Dim Back i st
  • 使用 TPL 数据流的请求/响应模式

    我们遇到一个问题 在使用 TPL 数据流库时需要请求 响应模式 我们的问题是我们有一个调用依赖服务的 NET core API 依赖服务限制并发请求 我们的API不限制并发请求 因此 我们一次可以收到数千个请求 在这种情况下 依赖服务将在达
  • 如何编译wxsqlite3和sqlite以获得加密支持

    我正在开发一个基于 wxWidgets 的 C 项目 使用wxSqlite3访问sqlite数据库 并且工作正常 但我想为数据库添加一些加密 在这里我通过 wxSqlite3 访问加密数据库时遇到问题 据我所知 sqlite默认不支持加密
  • Ansible 使用了错误版本的 Python

    我已经处理这个问题几天了 我在树莓派上运行ansible 我已将Python3 7设为Python的默认版本 显然 Ansible 希望使用 Python 2 7 我已在 playbook 的 vars 中添加了版本 3 7 但这不会更改模
  • 在全屏 Win32 OpenGL 中处理最小化

    我正在尝试使用 Win32 和 OpenGL 创建一个全屏应用程序 我使用更改分辨率EnumDisplaySettings and ChangeDisplaySettings并且 OpenGL 功能运行良好 在其 WndProc 上 我处理
  • Swing 中的进度对话框

    我怎样才能制作模态JDialog没有按钮出现的持续时间需要Runnable实例完成并让该实例更新该对话框上的进度条 消息 显然意大利面条代码可能有效 但我正在寻找一种干净的设计 如果存在 您可能想调查一下进度监视器 如果操作时间较长 会自动
  • .Net 控制计算机之间大小的变化

    我有一个奇怪的问题 我需要弄清楚如何解决 过去几周我一直在我的笔记本电脑上开发一个项目 但是当我在其中一台工作电脑上打开程序时 很多控件的尺寸错误和重叠等 机器之间的差异是这样的 Laptop Windows 7 专业版 显示 1920 1
  • 在MySQL中,我们如何判断表的索引是否是聚集索引?

    在MySQL中 我们如何判断表的索引是否是聚集索引 我们可以用show index from table name获取有关表索引的信息 但我没有发现它显示每个索引是聚集的还是非聚集的 这样做的目的是MySQL中如果一个表有索引 那么该表就必
  • Django FormWizard 动态改变 form_list

    我在使用表单向导时遇到了一些问题 也许有人可以解释一下 根据 process step 方法中的文档字符串 我可以 动态更改 self form list 因此 根据我的项目需求 我将表单附加到 form list 中 我附加的表格包含问题
  • 在外发电子邮件 EWS 中设置回复地址

    运行交换 2013 我在 C 服务中使用 EWS 该服务从服务帐户发送电子邮件 我想让电子邮件有一个与发送帐户不同的回复地址 即通讯组列表地址 我怎样才能做到这一点 这EmailMessage ReplyTo字段是只读的 Code Exch
  • Django 快捷方式嵌套外键

    假设我的 models py 中有以下内容 class Book pass class Part book models ForeignKey Book class Chapter part models ForeignKey Part n
  • 它不会创建 Java VM (JNI)

    我的简单命令行应用程序 int tmain int argc TCHAR argv JavaVM jvm JNIEnv env JavaVMInitArgs vm args JavaVMOption options 1 options 0
  • 扩展server_name(SNI扩展)不与jdk1.8.0一起发送,但与jdk1.7.0一起发送

    我已经使用 ApacheCXF v3 0 4 实现了 JAX WS 客户端 一切正常 但当我想使用 java 8 jdk1 8 0 25 的安全连接 SSL TLS 时 问题就出现了 我在日志中看到以下异常 Djavax net debug
  • 如何在未知输入类型下使用 cin?

    我有一个 C 程序 需要接受用户输入 用户输入要么是两个整数 例如 1 3 要么是一个字符 例如 s 我知道我可以像这样得到两个整数 cin gt gt x gt gt y 但是 如果输入的是 char 我该如何获取 cin 的值呢 我知道
  • 在 IIS Express 中配置最大请求数

    如何配置 IIS Express 中允许的最大请求数 我想将其更改为仅允许一些请求来测试超出限制时会发生什么 可以使用以下方式配置 IIS ExpressapplicationHost config文件 它位于 userprofile my
  • Java - 如何将 PDF 打印到特定打印机?

    我在 Windows 8 1 中有 5 台打印机 并且 PDF 文件不在本地系统中 而是在 PHP 服务器中生成的 问题 如何从服务器获取 PDF 文件并打印到特定打印机 我正在尝试使用 Apache PDFBox 2 0 0 EDIT i
  • 如何分解行? [复制]

    这个问题在这里已经有答案了 我有一个数据表 如下所示 cep3 lt structure list lat c 23 39429 23 39988 23 38233 23 39009 23 40135 23 4019 lon c 46 32
  • 替换 tel 或 telprompt 拨打电话

    我制作了一个应用程序 用于在按下按钮时呼叫预定义的号码 据我所知 在应用程序内拨打电话的唯一方法是使用 tel 或 telprompt 当我提交应用程序时 我收到了带有以下描述的拒绝 2 5 详情 您的应用程序使用或引用以下非公共 API
  • php中事件的含义

    我也知道php和nodejs 在javascript中我们有异步编程 所以我理解其中事件的含义 但是我看到了Yii 和 Zend 2 中的事件也使用它们 但我无法理解它的含义 它在 php 中如何工作以及它到底有什么作用 首先 PHP中没有