当我使用Laravel Tinker会话在Observer类中摆弄模型时,有什么方法可以捕捉?

时间:2019-05-10 00:08:39

标签: laravel observers tinker

我将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类中的模型时,是否有一种方法可以捕获?

1 个答案:

答案 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->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. 
    }
}