Dieser ist knifflig. Kurze Version: Entfernen Sie Ihre Rückgabewerte von Ihren Handlern und beide Ereignisse werden ausgelöst. Lange Version folgt.
Erstens, ich werde Sie übernehmen soll MyParent
(nicht myParent
) geben, dass Sie Ihre boot
Methoden gemeint protected
zu sein, und nicht private
, und dass Sie eine endgültige )
in Ihrem create
Methodenaufrufe enthalten. Andernfalls wird der Code nicht ausgeführt. :)
Allerdings ist das Problem, das Sie beschreiben, real. Der Grund dafür ist, dass beredte Ereignisse als "haltende" Ereignisse gelten. Das heißt, wenn bei einigen Ereignissen irgendein Nicht-Null-Wert von den Event-Handlern zurückgegeben wird (sei es ein Closure- oder PHP-Callback), wird das Ereignis nicht weiter verbreitet. Sie können dies in den
#File: vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php
public function fire($event, $payload = array(), $halt = false)
{
}
Dispatcher sehen $halt
diesen dritten Parameter sehen? Später, während der Dispatcher Ereignis-Listener ist
#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;
}
//...
Wenn halt true
und der Rückruf zurückgegeben ruft etwas, die nicht null ist (true
, false
, ein sclaer Wert, ein array
, ein object
), die fire
Verfahren Kurzschlüsse mit einem return $response
, und die Ereignisse stoppen sich zu verbreiten. Dies ist über diesen Standard hinaus "false
zurückgeben, um die Ereignisausbreitung zu stoppen". Einige Ereignisse haben Halt eingebaut.
Also, welche Model Events anhalten? Wenn Sie bei der Definition von fireModelEvent
in der Basis eloquent Modellklasse aussehen (Laravel Aliase dies als Eloquent
)
#File: vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php
protected function fireModelEvent($event, $halt = true)
{
//...
}
können Sie ein Modell der Ereignisse Standard zu Anhalten sehen.Also, wenn wir das Modell aussehen durch Veranstaltungen zum Brennen, sehen wir die Ereignisse, die tun halt sind
#File: vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php
$this->fireModelEvent('deleting')
$this->fireModelEvent('saving')
$this->fireModelEvent('updating')
$this->fireModelEvent('creating')
und Ereignisse, die
#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);
nicht aufhalten werden Sie sehen, creating
ist ein Halteereignis, weshalb das Zurückgeben eines Werts, auch true
, das Ereignis angehalten hat und Ihr zweiter Listener nicht ausgelöst wurde. Halteereignisse werden normalerweise verwendet, wenn die Model-Klasse etwas mit dem Rückgabewert eines Ereignisses ausführen möchte. Speziell für creating
#File: vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php
protected function performInsert(Builder $query)
{
if ($this->fireModelEvent('creating') === false) return false;
//...
wenn Sie false
zurückkehren, (nicht null) von Ihrem Rückruf, Laravel wird überspringen tatsächlich die INSERT
durchführen. Dies ist wiederum ein anderes Verhalten als bei der standardmäßigen Stop-Ereignisausbreitung durch Rückgabe von false. Bei diesen vier Modellereignissen wird durch die Rückgabe von false
auch die Aktion abgebrochen, auf die sie warten.
Entfernen Sie die Rückgabewerte (oder return null
) und Sie werden gut gehen.
AlanStorm netter! –
Brilliant! Ich nehme an, wenn ich genug nachdenke, macht es Sinn. Wenn ein Listener die Erstellung abbricht, sollten die anderen Listener nicht auslösen. Ich war nur überrascht, dass die Rückkehr "wahr" auch stockte. Anywho, tolle Erklärung AlanStorm - danke! – Anthony
@Anthony Es ist ein bisschen komisch/nicht offensichtlich, aber es gibt keinen leichten Sieg hier. Aus diesem Grund haben Systeme wie Drupal ein Ereignissystem für Ereignisse und ein "Hooks" -System für Ereignisse, die Daten manipulieren müssen. –