如何在laravel中将参数传递给监听器?
how to pass parameters to listener in laravel?
我是这样注册的LogConnectionFailed
:
protected $listen = [
Registered::class => [
SendEmailVerificationNotification::class,
],
'Illuminate\Http\Client\Events\ConnectionFailed' => [
'App\Listeners\LogConnectionFailed',
],
];
如果没有收到对给定请求的响应,则会触发 ConnectionFailed 事件。
my class {
public function send() {
$response = Http::get('http://example.com');
}
}
我需要在 LogConnectionFailed class.class.
中调用 http 客户端 class 的名称和发生这种情况的方法以及持续时间
这通过正常的参数传递是不可能的,所以我利用 PHP 原生函数 debug_backtrace()
并破解了它。
逻辑是当侦听器想要处理事件时,我们获取回调跟踪并通过调用堆栈帧进行过滤,直到找到我们的监视位置之一。
代码是这样的:
use Illuminate\Support\Str;
use Illuminate\Http\Client\Events\ConnectionFailed;
class LogConnectionFailed
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
public function handle(ConnectionFailed $event)
{
$backtraceCollection = Collect(debug_backtrace());
$callerClass = $backtraceCollection->first(function($value, $key) use ($event){
$class = $value['class'] ?? '';
return $this->classIsWatched($class);
});
if ($callerClass) {
// Store in DB or do some other stuff.
dd([
'class' => $callerClass['class'],
'function' => $callerClass['function'],
'line' => $callerClass['line'],
]);
} else {
dd("should skip. Not Watching classes.");
}
}
private function classIsWatched(string $className): bool
{
return Str::is(
['App\Http\Controllers\*', 'App\MyClass'],
$className
);
}
}
这里注意函数里面的数组classIsWatched
:
['App\Http\Controllers\*', 'App\MyClass']
这些是我们要监视的 classes 或目录,这意味着如果 ConnectionFailed
由于来自这些 classes 的一些调用,它们将被捕获,否则它们将被跳过。这使您可以灵活地过滤掉并观察应用程序中的某些位置。
请注意,我们还可以使用通配符 *
来简化路径包含。例如App\Http\Controllers\Api\EventController
也被观看了。
例如,如果我在 App
路径中有这个 class:
namespace App;
use Illuminate\Support\Facades\Http;
class MyClass
{
public static function callEvent()
{
$response = Http::get('http://example.com');
}
}
由于任何原因,如果 ConnectionFailed
事件调度,处理方法的输出将是:
array:3 [▼
"class" => "App\MyClass"
"function" => "callEvent"
"line" => 11
]
这将为您提供 class 名称、函数名称 甚至 行 那里引发了哪个事件。您可以简单地替换侦听器 handle
方法中的 dd()
并对数据执行您想要的操作。
关于Http Call的时长,我没有想出准确的答案,但是你可以用这个方法粗略估计一下:
dd(microtime(true) - LARAVEL_START);
在 handle
方法中也添加上面的代码,这给了你从应用程序启动的那一刻到你得到这个点的时间差(Http 请求失败,你进入了这个监听器) .
我是这样注册的LogConnectionFailed
:
protected $listen = [
Registered::class => [
SendEmailVerificationNotification::class,
],
'Illuminate\Http\Client\Events\ConnectionFailed' => [
'App\Listeners\LogConnectionFailed',
],
];
如果没有收到对给定请求的响应,则会触发 ConnectionFailed 事件。
my class {
public function send() {
$response = Http::get('http://example.com');
}
}
我需要在 LogConnectionFailed class.class.
中调用 http 客户端 class 的名称和发生这种情况的方法以及持续时间这通过正常的参数传递是不可能的,所以我利用 PHP 原生函数 debug_backtrace()
并破解了它。
逻辑是当侦听器想要处理事件时,我们获取回调跟踪并通过调用堆栈帧进行过滤,直到找到我们的监视位置之一。
代码是这样的:
use Illuminate\Support\Str;
use Illuminate\Http\Client\Events\ConnectionFailed;
class LogConnectionFailed
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
public function handle(ConnectionFailed $event)
{
$backtraceCollection = Collect(debug_backtrace());
$callerClass = $backtraceCollection->first(function($value, $key) use ($event){
$class = $value['class'] ?? '';
return $this->classIsWatched($class);
});
if ($callerClass) {
// Store in DB or do some other stuff.
dd([
'class' => $callerClass['class'],
'function' => $callerClass['function'],
'line' => $callerClass['line'],
]);
} else {
dd("should skip. Not Watching classes.");
}
}
private function classIsWatched(string $className): bool
{
return Str::is(
['App\Http\Controllers\*', 'App\MyClass'],
$className
);
}
}
这里注意函数里面的数组classIsWatched
:
['App\Http\Controllers\*', 'App\MyClass']
这些是我们要监视的 classes 或目录,这意味着如果 ConnectionFailed
由于来自这些 classes 的一些调用,它们将被捕获,否则它们将被跳过。这使您可以灵活地过滤掉并观察应用程序中的某些位置。
请注意,我们还可以使用通配符 *
来简化路径包含。例如App\Http\Controllers\Api\EventController
也被观看了。
例如,如果我在 App
路径中有这个 class:
namespace App;
use Illuminate\Support\Facades\Http;
class MyClass
{
public static function callEvent()
{
$response = Http::get('http://example.com');
}
}
由于任何原因,如果 ConnectionFailed
事件调度,处理方法的输出将是:
array:3 [▼
"class" => "App\MyClass"
"function" => "callEvent"
"line" => 11
]
这将为您提供 class 名称、函数名称 甚至 行 那里引发了哪个事件。您可以简单地替换侦听器 handle
方法中的 dd()
并对数据执行您想要的操作。
关于Http Call的时长,我没有想出准确的答案,但是你可以用这个方法粗略估计一下:
dd(microtime(true) - LARAVEL_START);
在 handle
方法中也添加上面的代码,这给了你从应用程序启动的那一刻到你得到这个点的时间差(Http 请求失败,你进入了这个监听器) .