1

Observer设置了 Listen to aModel的事件,以保持我Controller的 Logging 消息清洁。我的实现如下:

首先,一个 store 方法可以做它应该做的事情。从有效参数创建并保存新模型。

# 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()

所以我的问题如下:当我专门使用 Laraveltinker会话来处理 Observer 类中的模型时,有没有办法捕捉到?

4

1 回答 1

1

好的,回答我自己的问题:有办法。它需要使用一个Request对象。由于观察者不自己处理请求,我在构造函数中注入了一个。 可以使用 request() 代替,因此不需要 DI。

为什么请求很重要?

因为请求对象具有可访问的 $server 属性,该属性具有我想要的信息。这是我通过返回 a 获得的相关信息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->attributenull,因此没有访问未定义属性的风险)过滤所有这些属性。我也可以$request->server->has('attribute')(返回truefalse

# 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. 
    }
}
于 2019-05-10T16:32:56.853 回答