这个很棘手。简短版本:从您的处理程序中删除您的返回值,这两个事件都会触发。长版如下。
首先,我假设您的意思是输入MyParent(不是myParent),您的意思是您的boot 方法是protected,而不是private,并且您包含了一个在您的 create 方法调用中使用最终的 )。否则你的代码不会运行。 :)
但是,您描述的问题是真实的。原因是某些 Eloquent 事件被认为是“停止”事件。也就是说,对于某些事件,如果从事件处理程序(无论是闭包还是 PHP 回调)返回 any 非空值,则事件将停止传播。您可以在调度程序中看到这一点
#File: vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php
public function fire($event, $payload = array(), $halt = false)
{
}
看到第三个参数$halt了吗?稍后,当调度程序调用事件监听器时
#File: vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php
foreach ($this->getListeners($event) as $listener)
{
$response = call_user_func_array($listener, $payload);
// If a response is returned from the listener and event halting is enabled
// we will just return this response, and not call the rest of the event
// listeners. Otherwise we will add the response on the response list.
if ( ! is_null($response) && $halt)
{
array_pop($this->firing);
return $response;
}
//...
如果 halt 是 true 并且回调返回 anything 不为空(true、false、sclaer 值、array、object),则 @ 987654336@ 方法与return $response 短路,事件停止传播。这超出了标准“返回false 以停止事件传播”。某些事件已停止内置。
那么,哪些模型事件会停止?如果您查看基本 eloquent 模型类中 fireModelEvent 的定义(Laravel 将其别名为 Eloquent)
#File: vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php
protected function fireModelEvent($event, $halt = true)
{
//...
}
您可以看到模型的事件默认为停止。因此,如果我们查看触发事件的模型,我们会看到做停止的事件是
#File: vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php
$this->fireModelEvent('deleting')
$this->fireModelEvent('saving')
$this->fireModelEvent('updating')
$this->fireModelEvent('creating')
不停止的事件是
#File: vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php
$this->fireModelEvent('booting', false);
$this->fireModelEvent('booted', false);
$this->fireModelEvent('deleted', false);
$this->fireModelEvent('saved', false);
$this->fireModelEvent('updated', false);
$this->fireModelEvent('created', false);
如您所见,creating 是一个暂停事件,这就是为什么返回任何值,甚至是 true,都会暂停该事件并且您的第二个侦听器没有触发。当模型类想要对事件的返回值做某事时,通常会使用停止事件。专门针对creating
#File: vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php
protected function performInsert(Builder $query)
{
if ($this->fireModelEvent('creating') === false) return false;
//...
如果你从回调中返回false,(非空),Laravel 实际上会跳过执行INSERT。同样,这与标准通过返回 false 来停止事件传播的行为不同。对于这四个模型事件,返回 false 也会取消他们正在监听的动作。
删除返回值(或return null),一切顺利。