event类型 php,深入解析PHP的Laravel框架中的event事件操作

2023-11-16

有时候当我们单纯的看 Laravel 手册的时候会有一些疑惑,比如说系统服务下的授权和事件,这些功能服务的应用场景是什么,其实如果没有经历过一定的开发经验有这些疑惑是很正常的事情,但是当我们在工作中多加思考会发现有时候这些服务其实我们一直都见过。下面就事件、事件监听举一个很简单的例子你就会发现。

​ 这个例子是关于文章的浏览数的实现,当用户查看文章的时候文章的浏览数会增加1,用户查看文章就是一个事件,有了事件,就需要一个事件监听器,对监听的事件发生后执行相应的操作(文章浏览数加1),其实这种监听机制在 Laravel 中是通过观察者模式实现的.

注册事件以及监听器首先我们需要在 app/Providers/目录下的EventServiceProvider.php中注册事件监听器映射关系,如下:

protected $listen = [

'App\Events\BlogView' => [

'App\Listeners\BlogViewListener',

],

];

然后项目根目录下执行如下命令

php artisan event:generate

该命令完成后,会分别自动在 app/Events和app/Listensers目录下生成 BlogView.php和BlogViewListener.php文件。

定义事件

namespace App\Events;

use App\Events\Event;

use App\Post;

use Illuminate\Queue\SerializesModels;

use Illuminate\Contracts\Broadcasting\ShouldBroadcast;

class BlogView extends Event

{

use SerializesModels;

/**

* Create a new event instance.

*

* @return void

*/

public function __construct(Post $post)

{

$this->post = $post;

}

/**

* Get the channels the event should be broadcast on.

*

* @return array

*/

public function broadcastOn()

{

return [];

}

}

其实看到这些你会发现该事件类只是注入了一个 Post实例罢了,并没有包含多余的逻辑。

定义监听器事件监听器在handle方法中接收事件实例,event:generate命令将会自动在handle方法中导入合适的事件类和类型提示事件。在handle方法内,你可以执行任何需要的逻辑以响应事件,我们的代码实现如下:

namespace App\Listeners;

use App\Events\BlogView;

use Illuminate\Queue\InteractsWithQueue;

use Illuminate\Contracts\Queue\ShouldQueue;

use Illuminate\Session\Store;

class BlogViewListener

{

protected $session;

/**

* Create the event listener.

*

* @return void

*/

public function __construct(Store $session)

{

$this->session = $session;

}

/**

* Handle the event.

*

* @param BlogView $event

* @return void

*/

public function handle(BlogView $event)

{

$post = $event->post;

//先进行判断是否已经查看过

if (!$this->hasViewedBlog($post)) {

//保存到数据库

$post->view_cache = $post->view_cache + 1;

$post->save();

//看过之后将保存到 Session

$this->storeViewedBlog($post);

}

}

protected function hasViewedBlog($post)

{

return array_key_exists($post->id, $this->getViewedBlogs());

}

protected function getViewedBlogs()

{

return $this->session->get('viewed_Blogs', []);

}

protected function storeViewedBlog($post)

{

$key = 'viewed_Blogs.'.$post->id;

$this->session->put($key, time());

}

}

注释中也已经说明了一些逻辑。

触发事件事件和事件监听完成后,我们要做的就是实现整个监听,即触发用户打开文章事件在此我们使用和 Event提供的 fire方法,如下:

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Post;

use Illuminate\Support\Facades\Event;

use App\Http\Requests;

use App\Events\BlogView;

use App\Http\Controllers\Controller;

class BlogController extends Controller

{

public function showPost($slug)

{

$post = Post::whereSlug($slug)->firstOrFail();

Event::fire(new BlogView($post));

return view('home.blog.content')->withPost($post);

}

}

现在打开页面发现数据库中的`view_cache已经正常加1了,这样整个就完成了。

事件广播简介:

Laravel 5.1 之中新加入了事件广播的功能,作用是把服务器中触发的事件通过websocket服务通知客户端,也就是浏览器,客户端js根据接受到的事件,做出相应动作。本文会用简单的代码展示一个事件广播的过程。

依赖:

redis

nodejs, socket.io

laravel 5.1

配置:

config/broadcasting.php中,如下配置'default' => env('BROADCAST_DRIVER', 'redis'),,使用redis作为php和js的通信方式。

config/database.php中配置redis的连接。

定义一个被广播的事件:

根据Laravel文档的说明,想让事件被广播,必须让Event类实现一个Illuminate\Contracts\Broadcasting\ShouldBroadcast接口,并且实现一个方法broadcastOn。broadcastOn返回一个数组,包含了事件发送到的channel(频道)。如下:

namespace App\Events;

use App\Events\Event;

use Illuminate\Queue\SerializesModels;

use Illuminate\Contracts\Broadcasting\ShouldBroadcast;

class SomeEvent extends Event implements ShouldBroadcast

{

use SerializesModels;

public $user_id;

/**

* Create a new event instance.

*

* @return void

*/

public function __construct($user_id)

{

$this->user_id = $user_id;

}

/**

* Get the channels the event should be broadcast on.

*

* @return array

*/

public function broadcastOn()

{

return ['test-channel'];

}

}

被广播的数据:

默认情况下,Event中的所有public属性都会被序列化后广播。上面的例子中就是$user_id这个属性。你也可以使用broadcastWith这个方法,明确的指出要广播什么数据。例如:

public function broadcastWith()

{

return ['user_id' => $this->user_id];

}

Redis和Websocket服务器:

需要启动一个Redis,事件广播主要依赖的就是redis的sub/pub功能,具体可以看redis文档

需要启动一个websocket服务器来和client通信,建议使用socket.io,代码如下:

var app = require('http').createServer(handler);

var io = require('socket.io')(app);

var Redis = require('ioredis');

var redis = new Redis('6379', '192.168.1.106');

app.listen(6001, function() {

console.log('Server is running!');

});

function handler(req, res) {

res.writeHead(200);

res.end('');

}

io.on('connection', function(socket) {

console.log('connected');

});

redis.psubscribe('*', function(err, count) {

console.log(count);

});

redis.on('pmessage', function(subscribed, channel, message) {

console.log(subscribed);

console.log(channel);

console.log(message);

message = JSON.parse(message);

io.emit(channel + ':' + message.event, message.data);

});

这里需要注意的是redis.on方法的定义,接收到消息后,给client发送一个事件,事件名称为channel + ':' + message.event。

客户端代码:

客户端我们也使用socket.io,作为测试,代码尽量简化,仅仅打印一个接受到的数据即可。如下:

var socket = io('http://localhost:6001');

socket.on('connection', function (data) {

console.log(data);

});

socket.on('test-channel:App\\Events\\SomeEvent', function(message){

console.log(message);

});

console.log(socket);

服务器触发事件:

直接在router中定义个事件触发即可。如下:

Route::get('/event', function(){

Event::fire(new \App\Events\SomeEvent(3));

return "hello world";

});

测试:

启动redis

启动websocket

打开带有客户端代码的页面,可以看到websocket已经连接成功。

触发事件,打开另一个页面 localhost/event。

这时就可以发现,第一个页面的console中打印出了Object{user_id: 3},说明广播成功。

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

event类型 php,深入解析PHP的Laravel框架中的event事件操作 的相关文章

  • 超详细的springBoot学习教程

    springBoot学习 https docs spring io spring boot docs 2 2 6 RELEASE reference html index html 官方文档 1 搭建springBoot项目架构 2 spr
  • C#执行JavaScript脚本

    目录 安装和配置 执行 JavaScript 脚本 与脚本交互 JS 调用 C 方法 多线程使用 总结 ClearScript 是一个 NET 平台下的开源库 用于在 C 和其他 NET 语言中执行脚本代码 它提供了一种方便和安全的方法来将
  • Windows操作系统知识合集

    Windows操作系统的权限 Guest权限 User权限 人类可用普通权限 Administrator 人类可用最高权限的用户 System 系统 机器可用最高权限 比人类权限高更多 TrustInstaller 操作系统的最高权限 比S
  • Aggressive cows-疯牛POJ(2456)-详解

    描述 农夫 John 建造了一座很长的畜栏 它包括N 2 lt N lt 100 000 个隔间 这些小隔间依次编号为x1 xN 0 lt xi lt 1 000 000 000 但是 John的C 2 lt C lt N 头牛们并不喜欢这
  • verilog-mode的简要介绍

    verilog mode是什么 官网的介绍 https www veripool org wiki verilog mode Verilog mode el is the extremely popular free Verilog mod
  • 静态代理模式

    1 所谓的静态代理模式应该就是把大家都会做的相同的事情交给代理去做 2 而一定要自己做的事就在代理中传入一个自己的对象再在代理的类中的该方法中调用自己的方法 3 将所有需要自己完成的方法放在一个接口中然后自己和代理都去继承他 代理还会添加一
  • invalid resource directory name

    遇到错误 当有res navigation的时候 反编译打包回apk的时候会报错 invalid resource directory name res navigation 或者是 invalid resource directory n
  • 【CV】第 15 章:结合计算机视觉和 NLP 技术

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • pc微信禁止启动小程序

    场景 最近 Windows 微信的更新了可以访问小程序的功能 但还不完善 如 尝试播放激励视频时 会直接跳过视频并作为已完成处理等 身为开发者的我们可能需要做一些处理 禁止pc的微信访问小程序 以达到减小损失的目的 提要 App onLau
  • Google Cast(Chromecast)浏览器 SDK 学习笔记(一)

    前几天因为京东打折 买了个索尼的 SRS X77 音箱 看说明书说支持 Google Cast 试了试感觉还挺好用 于是研究了一下 Google Cast 的 SDK Chromecast Google Cast 傻傻分不清楚 Google
  • Python迭代器及其用法

    列表 list 元组 tuple 字典 dict 集合 set 这些序列式容器有一个共同的特性 它们都支持使用 for 循环遍历存储的元素 都是可迭代的 因此它们又有一个别称 即迭代器 从字面来理解 迭代器指的就是支持迭代的容器 更确切的说
  • Umi4各种运行报错排查

    使用 Umi4 搭建项目 选择antd pro模版 pnpm 运行起来以后VScode编译器中出现报红 但是项目正常运行 现在强迫症处理各种报红 如果有用请点个赞 o 1 Cannot find module umi or its corr
  • windows平台对NUMA的支持

    微软官网链接 https docs microsoft com en us windows win32 procthread numa support 译文如下 多处理器支持的传统模型是对称多处理器 SMP 在这种模型中 每个处理器对内存和
  • go mod 引入指定的分支

    方式一 执行以下命令 go get git地址 分支名 如 go get github com golang go master 方式二 直接在go mod文件中添加 格式如下 git地址 v0 0 0 时间戳 commint id 例如
  • webpack静态资源地址注入html,HtmlWebpackPlugin

    说明 插件的基本作用就是生成 html 文件 原理很简单 将 webpack 中entry配置的相关入口 chunk 和 extract text webpack plugin抽取的 css 样式 插入到该插件提供的template或者te
  • 拼多多电商玩家快速采集平台数据

    作为电商卖家 选款是一件很重要的事情 所以我们在选款上面需要下大功夫分析数据 如何第一时间知晓同类商品及其价格 如何实时采集到新款 爆款 及其价格 下面我对比两种方法 看看哪种方式更适合我们普通电商从业人员 目标 抓取拼多多某类商品的列表页
  • 学习Python数据分析有什么用?

    在当今信息爆炸的时代 数据成为了各行各业中不可或缺的资源 而Python作为一种高级编程语言 拥有强大的数据分析能力 本文将详细介绍学习Python数据分析的重要性以及它在实际应用中的用途 帮助读者更好地了解并学习Python数据分析 一
  • 基于ARIMA-CNN-LSTM预测模型研究(Python代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 1 1 A IMA 模型 1 2 CNN LSTM 模型 2 运行结果 3 参考文献 4 Python代码
  • 使用SDWAN构建安全的混合WAN

    使用SD WAN构建安全的混合WAN SDWAN的爆炸已成为头条新闻了一年多 企业正在以惊人的速度采取SDWAN 不但可以为分支机构提供更灵活的连接和利用程序性能 而且可以跨全部网络提供 远程 超级用户 依托SDWAN 通过将小型台式机装备

随机推荐

  • 博途 V15.1安装步骤

    温馨提醒 安装此软件电脑配置至少应满足以下要求 处理器 CoreTM i5 3320M 3 3 GHz 或相当 内存 至少8G 硬盘 300 GB SSD 显示器 15 6 宽屏显示 1920 x 1080 1 双击打开 Siemens v
  • 小程序代码提审用户隐私保护协议修改指引

    为规范开发者的用户个人信息处理行为 保障用户合法权益 小程序涉及处理用户个人信息的开发者 均需补充相应用户隐私保护指引 微信会根据小程序版本隐私接口调用情况展示必填项 开发者可自主勾选其他项目 一 代码提审版本用户隐私保护指引填写入口 管理
  • 用c99 写的简单线程池类

    include
  • [培训-DSP快速入门-6]:C54x DSP开发中C语言库函数的使用

    作者主页 文火冰糖的硅基工坊 https blog csdn net HiWangWenBing 本文网址 https blog csdn net HiWangWenBing article details 119010855 目录 第1章
  • 14 代码分割之lazy:Suspense与路由懒加载

    lazy内置方法 Suspense内置组件 lazy是React提供的懒 动态 加载组件的方法 React lazy 能减少打包体积 延迟加载首屏不需要渲染的组件 依赖内置组件Suspense 给lazy加上loading指示器组件的一个容
  • 【面试题】前端开发中如何高效渲染大数据量?

    前端面试题库 面试必备 推荐 地址 前端面试题库 国庆头像 国庆爱国 程序员头像 总有一款适合你 在日常工作中 较少的能遇到一次性往页面中插入大量数据的场景 数栈的离线开发 以下简称离线 产品中 就有类似的场景 本文将分享一个实际场景中的前
  • 一大波 Android 刘海屏来袭,全网最全适配技巧!

    一 序 Hi 大家好 我是承香墨影 Apple 一直在引领设计的潮流 自从 iPhone X 发布之后 刘海屏 就一直存在争议 不过不管你怎样 Android 也要跻入 刘海屏 的行列 尤其是 Android P 发布之后 也从系统级支持顶
  • mysql auto connect_Mysql autoReconnect 的问题

    MySQL官方不推荐使用autoReconnect true 参见 http bugs mysql com bug php id 5020 需要另外找别的办法来解决超过8小时 链接断开的问题 由于问题产生的根本原因在于服务到数据库的连接长时
  • mysql的workbench在哪_MySQL Workbench的使用方法(图文)

    MySQLWorkbench 是 MySQL AB 最近释放的可视数据库设计工具 这个工具是设计 MySQL数据库的专用工具 MySQLWorkbench 拥有很多的功能和特性 这篇由DjoniDarmawikarta 写的文章通过一个示例
  • JavaScript将一层级对象数组转为children嵌套的三层级树状对象数组(多级树状分类)

    有时候后端返回的数据不适合前端 我们就需要进行转换 比如我想用elementUI的级联选择器 而这个组件对数据格式有要求 本篇文章将介绍如何将一层级对象数组数据格式转为三层级嵌套children数组 JavaScript Vue 小程序等都
  • 信息学奥赛一本通 1240:查找最接近的元素

    题目链接 http ybt ssoier cn 8088 problem show php pid 1240 include
  • 数据库相关知识和进阶知识

    目录 MySQL与Orcale EXPLAIN介绍 EXPLAIN 可以分析慢查询原因 查看MySQL存储空间大小 MySQL事务锁不执行严格的校验
  • Retrofit实现文件上传和下载【二】

    概述 通过前一篇的博客介绍 我们已经对Retrofit的使用有了一个大概的了解 今天来讲讲利用Retrofit进行文件的上传和下载 文件上传 服务器使用的是SSH框架 因此这里是以struts2的方式来获取数据的 我这里定义了三个字段用来接
  • Java发送手机短信验证码

    本次使用的是阿里云的短信服务 1 添加短信签名 签名名称要用的 在阿里云产品中搜 短信服务 gt 免费开通 gt 国内消息 2 添加短信模板 模版CODE需要用的 就在添加签名的旁边 3 创建用户 用户令牌和密码需要用的 然后选择 开始使用
  • bug复刻,解决方案---在改变div层级关系时,导致传参失败

    问题描述 在优化页面时 为了实现网页顶部遮挡效果 内容滚动 顶部导航栏不随着一起滚动 并且覆盖 做法是将内容都放在一个div里面 为这个新的div设置样式 margin top width heigh等 网页效果的确实现了 但是出现的新的问
  • Chisel实验笔记(一)

    最近在学习Risc v 其中伯克利大学开源了一款兼容Risc v指令集的处理器Rocket 而Rocket处理器是采用Chisel编写的 所以要学习Chisel Chisel的简单介绍如下 Chisel Constructing Hardw
  • 基于Arduino的音乐动感节奏灯

    1 音乐动感节奏灯是个什么东西 前段时间听音乐觉得无聊 便想着音乐光听也没意思啊 能不能 看见 音乐呢 于是谷歌了一番 发现还真有人做了将音乐可视化的东西 那就是音乐节奏灯 说的简单点就是LED灯光颜色亮度等随着音乐的节奏而发生变化 看了下
  • 最新机器人工程专业毕设选题推荐

    文章目录 1前言 2 如何选题 3 机器人工程 毕设 选题推荐 4 最后 1前言 近期不少学弟学妹询问学长关于机器人工程专业工程专业相关的毕设选题 学长特意写下这篇文章以作回应 以下是学长亲手整理相关的毕业设计选题 都是经过学长精心审核的题
  • Python-声明变量

    Python如何声明变量 在 Python 中 定义变量非常简单 只需要为变量赋一个值即可自动创建该变量 并推断出变量的数据类型 变量名可以是任意字母 数字或下划线组成 但是不能以数字开头 例如 定义名为 name 的变量 并将字符串 To
  • event类型 php,深入解析PHP的Laravel框架中的event事件操作

    有时候当我们单纯的看 Laravel 手册的时候会有一些疑惑 比如说系统服务下的授权和事件 这些功能服务的应用场景是什么 其实如果没有经历过一定的开发经验有这些疑惑是很正常的事情 但是当我们在工作中多加思考会发现有时候这些服务其实我们一直都