《PHP教程:深入解析PHP的Laravel框架中的event事件操作》要点:
本文介绍了PHP教程:深入解析PHP的Laravel框架中的event事件操作,希望对您有用。如果有疑问,可以联系我们。
PHP实例 有时候当我们单纯的看 Laravel 手册的时候会有一些疑惑,好比说系统服务下的授权和事件,这些功能服务的应用场景是什么,其实如果没有经历过一定的开发经验有这些疑惑是很正常的事情,但是当我们在工作中多加思考会发现有时候这些服务其实我们一直都见过.下面就事件、事件监听举一个很简单的例子你就会发现.
PHP实例 这个例子是关于文章的浏览数的实现,当用户查看文章的时候文章的浏览数会增加1,用户查看文章就是一个事件,有了事件,就必要一个事件监听器,对监听的事件发生后执行相应的操作(文章浏览数加1),其实这种监听机制在 Laravel 中是通过观察者模式实现的.
PHP实例注册事件以及监听器
首先我们必要在 app/Providers/目录下的EventServiceProvider.php中注册事件监听器映射关系,如下:
PHP实例
protected $listen = [
'App\Events\BlogView' => [
'App\Listeners\BlogViewListener',
],
];
PHP实例然后项目根目录下执行如下命令
PHP实例
php artisan event:generate
PHP实例该命令完成后,会分别自动在 app/Events和app/Listensers目录下生成 BlogView.php和BlogViewListener.php文件.
PHP实例定义变乱
PHP实例
<?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 [];
}
}
PHP实例其实看到这些你会发现该事件类只是注入了一个 Post实例而已,并没有包含多余的逻辑.
PHP实例定义监听器
事件监听器在handle办法中接收事件实例,event:generate命令将会自动在handle办法中导入合适的事件类和类型提示事件.在handle办法内,你可以执行任何需要的逻辑以响应事件,我们的代码实现如下:
PHP实例
<?php
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());
}
}
PHP实例注释中也已经说明了一些逻辑.
PHP实例触发事件
事件和事件监听完成后,我们要做的就是实现整个监听,即触发用户打开文章事件在此我们使用和 Event提供的 fire办法,如下:
PHP实例
<?php
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);
}
}
PHP实例现在打开页面发现数据库中的`view_cache已经正常加1了,这样整个就完成了.
PHP实例事件广播
简介:
Laravel 5.1 之中新加入了事件广播的功能,作用是把服务器中触发的事件通过websocket服务通知客户端,也便是浏览器,客户端js根据接受到的事件,做出相应动作.本文会用简单的代码展示一个事件广播的过程.
PHP实例依赖:
PHP实例配置:
PHP实例定义一个被广播的事件:
根据Laravel文档的说明,想让事件被广播,必须让Event类实现一个Illuminate\Contracts\Broadcasting\ShouldBroadcast接口,并且实现一个办法broadcastOn.broadcastOn返回一个数组,包含了事件发送到的channel(频道).如下:
PHP实例
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'];
}
}
PHP实例被广播的数据:
默认情况下,Event中的所有public属性都会被序列化后广播.上面的例子中就是$user_id这个属性.你也可以使用broadcastWith这个办法,明确的指出要广播什么数据.例如:
PHP实例
public function broadcastWith()
{
return ['user_id' => $this->user_id];
}
PHP实例Redis和Websocket服务器:
必要启动一个Redis,事件广播主要依赖的就是redis的sub/pub功能,具体可以看redis文档
必要启动一个websocket服务器来和client通信,建议使用socket.io,代码如下:
PHP实例
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);
});
PHP实例这里需要注意的是redis.on办法的定义,接收到消息后,给client发送一个事件,事件名称为channel + ':' + message.event.
PHP实例客户端代码:
客户端我们也使用socket.io,作为测试,代码尽量简化,仅仅打印一个接受到的数据即可.如下:
PHP实例
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);
PHP实例服务器触发变乱:
直接在router中定义个变乱触发即可.如下:
PHP实例
Route::get('/event', function(){
Event::fire(new \App\Events\SomeEvent(3));
return "hello world";
});
PHP实例测试:
PHP实例这时就可以发现,第一个页面的console中打印出了Object{user_id: 3},说明广播成功.
欢迎参与《PHP教程:深入解析PHP的Laravel框架中的event事件操作》讨论,分享您的想法,维易PHP学院为您提供专业教程。
转载请注明本页网址:
http://www.vephp.com/jiaocheng/7273.html