我将Observer
设置为侦听Model
的事件,以使我的Controller
免受日志记录消息的影响。我的实现如下:
首先,一个存储方法执行应做的事情。根据有效参数创建并保存新模型。
# app/Http/Controllers/ExampleController.php
namespace App\Http\Controllers;
use App\Http\Requests\StoreExample;
use App\Example;
class ExampleController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
/**
* Create and save an Example from validated form parameters.
* @param App\Http\Requests\StoreExample $request
*/
public function store(StoreExample $request)
{
Example::create($request->validated());
return back();
}
}
StoreExample
表单请求并不重要。它只是验证并检查授权动作的门。
我设置的Observer
记录了此操作。
# app/Observers/ExampleObserver.php
namespace App\Observers;
use App\Example;
class ExampleObserver
{
public function created(Example $example): void
{
\Log::info(auth()->id()." (".auth()->user()->full_name.") has created Example with params:\n{$example}");
}
}
我遇到的问题是,我的日志取决于要设置的auth()
对象的方式。给定auth
中间件和必须存储的示例门,来宾用户无法取消此代码。
但是,我确实喜欢在本地和暂存环境中使用tinker
来检查网站的行为,但这会引起错误(更确切地说,PHP notice
),因为我可以创建未经认证的Example
模型,并且记录器将尝试从非对象full_name
获取属性auth()->user()
。
所以我的问题如下:当我专门使用Laravel tinker
会话来处理Observer类中的模型时,是否有一种方法可以捕获?
答案 0 :(得分:0)
好的,回答我自己的问题: IS 是一种方法。它需要使用Request
对象。 由于观察者并不自己处理请求,因此我在构造函数中注入了一个请求。 可以使用request()代替,因此不需要DI。
因为请求对象具有可访问的$ server属性,该属性包含我想要的信息。这是我通过返回dd($request->server)
获得的相关信息(我不会粘贴整个内容。我的请求的ServerBag具有超过100个属性!)
Symfony\Component\HttpFoundation\ServerBag {#37
#parameters: array:123 [
"SERVER_NAME" => "localhost"
"SERVER_PORT" => 8000
"HTTP_HOST" => "localhost:8000"
"HTTP_USER_AGENT" => "Symfony" // Relevant
"REMOTE_ADDR" => "127.0.0.1"
"SCRIPT_NAME" => "artisan" // Relevant
"SCRIPT_FILENAME" => "artisan" // Relevant
"PHP_SELF" => "artisan" // Relevant
"PATH_TRANSLATED" => "artisan" // Relevant
"argv" => array:2 [ // Relevant
0 => "artisan"
1 => "tinker"
]
"argc" => 2
]
}
因此,我可以使用$request->server('attribute')
过滤所有这些属性(返回$request->server->attribute
或null
,因此没有访问未定义属性的风险)。我也可以做$request->server->has('attribute')
(返回true
或false
)
# app/Observers/ExampleObserver.php
namespace App\Observers;
use App\Example;
class ExampleObserver
{
/* Since we can use request(), there's no need to inject a Request into the constructor
protected $request;
public function __construct(Request $request)
{
$this->request = $request;
}
*/
public function created(Example $example): void
{
\Log::info($this->getUserInfo()." has created Example with params:\n{$example}");
}
private function getUserInfo(): string
{
// My logic here.
}
}