백엔드 개발 PHP 튜토리얼 PHP Laravel 프레임워크의 이벤트 동작 분석

PHP Laravel 프레임워크의 이벤트 동작 분석

Jun 13, 2018 am 11:32 AM
event laravel php 이벤트

这篇文章主要介绍了PHP的Laravel框架中的event事件操作,其中重点讲解了Laravel 5.1之中新加入了事件广播的功能,需要的朋友可以参考下

 有时候当我们单纯的看 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文件。

定义事件

<?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方法内,你可以执行任何需要的逻辑以响应事件,我们的代码实现如下:

<?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(&#39;viewed_Blogs&#39;, []);
  }

  protected function storeViewedBlog($post)
  {
    $key = &#39;viewed_Blogs.&#39;.$post->id;

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

}
로그인 후 복사

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

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

<?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(&#39;home.blog.content&#39;)->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 [&#39;test-channel&#39;];
  }
}
로그인 후 복사

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

public function broadcastWith()
{
  return [&#39;user_id&#39; => $this->user_id];
}
로그인 후 복사

Redis和Websocket服务器:
需要启动一个Redis,事件广播主要依赖的就是redis的sub/pub功能,具体可以看redis文档
需要启动一个websocket服务器来和client通信,建议使用socket.io,代码如下:

var app = require(&#39;http&#39;).createServer(handler);
var io = require(&#39;socket.io&#39;)(app);

var Redis = require(&#39;ioredis&#39;);
var redis = new Redis(&#39;6379&#39;, &#39;192.168.1.106&#39;);

app.listen(6001, function() {
  console.log(&#39;Server is running!&#39;);
});

function handler(req, res) {
  res.writeHead(200);
  res.end(&#39;&#39;);
}

io.on(&#39;connection&#39;, function(socket) {
  console.log(&#39;connected&#39;);
});

redis.psubscribe(&#39;*&#39;, function(err, count) {
  console.log(count);
});

redis.on(&#39;pmessage&#39;, function(subscribed, channel, message) {
  console.log(subscribed);
  console.log(channel);
  console.log(message);

  message = JSON.parse(message);
  io.emit(channel + &#39;:&#39; + message.event, message.data);
});
로그인 후 복사

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

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

var socket = io(&#39;http://localhost:6001&#39;);
socket.on(&#39;connection&#39;, function (data) {
  console.log(data);
});
socket.on(&#39;test-channel:App\\Events\\SomeEvent&#39;, function(message){
  console.log(message);
});
console.log(socket);
로그인 후 복사

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

Route::get(&#39;/event&#39;, function(){
  Event::fire(new \App\Events\SomeEvent(3));
  return "hello world";
});
로그인 후 복사

测试:

  • 启动redis

  • 启动websocket

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

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

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

위 내용은 이 글의 전체 내용입니다. 모든 분들의 학습에 도움이 되길 바랍니다. 더 많은 관련 내용은 PHP 중국어 홈페이지를 참고해주세요!

관련 권장사항:

PHP Laravel 프레임워크의 메시지 큐 큐 및 비동기 큐 사용 방법 분석 정보

Laravel을 사용하여 사용자 등록 및 로그인 구현

Aravel5의 뷰로 배열 전송 프레임워크 학습

위 내용은 PHP Laravel 프레임워크의 이벤트 동작 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

<gum> : Bubble Gum Simulator Infinity- 로얄 키를 얻고 사용하는 방법
1 몇 달 전 By 尊渡假赌尊渡假赌尊渡假赌
Nordhold : Fusion System, 설명
1 몇 달 전 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora : 마녀 트리의 속삭임 - Grappling Hook 잠금 해제 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

session_start () 함수의 중요성은 무엇입니까? session_start () 함수의 중요성은 무엇입니까? May 03, 2025 am 12:18 AM

session_start () iscrucialinphpformanagingUsersessions.1) itiniteSanewsessionifnoneexists, 2) ResumesAnxistessions, and3) setSasessionCookieForContInuityAcrosrequests, enablingplicationsirecationSerauthenticationAndpersonalizestContent.

작곡가 : PHP 개발자의 패키지 관리자 작곡가 : PHP 개발자의 패키지 관리자 May 02, 2025 am 12:23 AM

Composer는 PHP의 종속성 관리 도구이며 Composer.json 파일을 통해 프로젝트 종속성을 관리합니다. 1) 종속성 정보를 얻기 위해 Composer.json을 구문 분석합니다. 2) 종속성 트리를 형성하기위한 종속성; 3) Packagist에서 공급 업체 디렉토리로 종속성을 다운로드하여 설치합니다. 4) Composer.Lock 파일을 생성하여 팀 일관성 및 프로젝트 유지 관리 가능성을 보장하기 위해 종속성 버전을 잠그십시오.

Laravel 로그 및 오류 모니터링 : Sentry 및 Bugsnag 통합 Laravel 로그 및 오류 모니터링 : Sentry 및 Bugsnag 통합 Apr 30, 2025 pm 02:39 PM

Laravel에 Sentry와 Bugsnag를 통합하면 응용 프로그램 안정성과 성능이 향상 될 수 있습니다. 1. Composer.json에 Sentrysdk를 추가하십시오. 2. config/app.php에 센트리 서비스 제공 업체를 추가하십시오. 3. .env 파일에서 sentrydsn을 구성하십시오. 4. app \ exceptions \ handler.php에서 센트리 오류 보고서를 추가하십시오. 5. 센트리를 사용하여 예외를 잡고보고하고 추가 컨텍스트 정보를 추가하십시오. 6. app \ exceptions \ handler.php의 ugsnag 오류 보고서를 추가하십시오. 7. Bugsnag 모니터링을 사용하십시오

Laravel 라이브 채팅 응용 프로그램 : WebSocket 및 Pusher Laravel 라이브 채팅 응용 프로그램 : WebSocket 및 Pusher Apr 30, 2025 pm 02:33 PM

Laravel에서 라이브 채팅 애플리케이션을 구축하려면 WebSocket 및 Pusher를 사용해야합니다. 특정 단계에는 다음이 포함됩니다. 1) .env 파일의 푸시어 정보 구성; 2) 방송 드라이버를 Broadcasting.php 파일에 Pusher로 설정합니다. 3) 푸셔 채널을 구독하고 Laravelecho를 사용한 이벤트를 듣습니다. 4) 푸셔 API를 통해 메시지를 보내십시오. 5) 개인 채널 및 사용자 인증 구현; 6) 성능 최적화 및 디버깅을 수행하십시오.

JavaScript 프레임 워크 (React, Vue, Angular)와 Laravel 백엔드 통합 JavaScript 프레임 워크 (React, Vue, Angular)와 Laravel 백엔드 통합 May 03, 2025 am 12:20 AM

React, vue, andangularcanbeintegratedwithlaravelbyfollowspecificsetupsteps.1) forreact : installEactusingLaravelui, setupcomponentsinApp.js.2) Forvue : Uselaravel'sbuilt-Invuesupport, configureinApt.3)

HTML 요소의 회전 효과를 설정하는 방법 HTML 요소의 회전 효과를 설정하는 방법 Apr 30, 2025 pm 02:42 PM

HTML에서 요소의 회전 효과를 설정하는 방법은 무엇입니까? CSS 및 JavaScript를 사용하여 달성 할 수 있습니다. 1. CSS의 변환 속성은 회전 (45deg)과 같은 정적 회전에 사용됩니다. 2. JavaScript는 변환 속성을 변경하여 구현되는 회전을 동적으로 제어 할 수 있습니다.

PHP 성능 최적화 전략. PHP 성능 최적화 전략. May 13, 2025 am 12:06 AM

phPapplicationSCanBeoptimizedForsPeedandefficiencyby : 1) ENABLEOPCACHEINPHP.INI, 2) PREPAREDSTATEMENTSWITHPDOFORDATABASEQUERIES 사용

PHP의 종속성 주입을위한 모범 사례 PHP의 종속성 주입을위한 모범 사례 May 08, 2025 am 12:21 AM

의존성 주입 (DI)을 사용하는 이유는 코드의 느슨한 커플 링, 테스트 가능성 및 유지 관리 가능성을 촉진하기 때문입니다. 1) 생성자를 사용하여 종속성을 주입하고, 2) 서비스 로케이터 사용을 피하고, 3) 종속성 주입 컨테이너를 사용하여 종속성을 관리하고, 4) 주입 종속성을 통한 테스트 가능성을 향상 시키십시오.

See all articles