Application onShutdown – jak navěsit událost

martin.loucka
Člen | 9
+
0
-

Ahoj,

zjistil jsem, že na spouštění kódu na konci běhu aplikace by bylo ideální v mém případě využít Application::$onShutdown.

Chtěl bych se zeptat, jak takovou událost vyrobím? Dejme tomu, že jsem uprostřed Presenteru, a potřeboval bych zajistit, že na konci běhu aplikace se vypíše obsah nějaké proměnné z toho Presenteru.

Intuitivně bych si představoval, že na nějakém místě v Presenteru zavolám „cosi“, čím získám objekt Application, a na něj zavolám ->onShutdown[] = function() {…}.

Poradíte prosím, co je to „cosi“? Nebo jsem úplně mimo?

Díky moc,

Martin

Milo
Nette Core | 1283
+
0
-

Aplikaci si nech injectnout. Nebo použij obdobnou onShutdown[] na presenteru.

Jen tedy v shutdown fázi cokoliv vypisovat mi přijde už pozdě.

martin.loucka
Člen | 9
+
0
-

Diky moc, vyzkousim.

Je to pro ucely ladeni/debuggingu, nebude to permanentni design :-).

OnShutdown na Presenteru nepomuze, protoze se vola prilis brzy (kdyz si dumpnu neco pri vytvareni kazde komponenty a zaroven neco na Presenter::$onShutdown, tak se fakt brzy vypise ten dump z shutdownu a pak je tam spousta dalsich dumpu z vytvareni tech komponent).

Felix
Nette Core | 1186
+
-3
-

Ahoj @martin.loucka. Muzes vyzkouset i contributte/event-dispatcher-extra. Pak lze na tyto eventy registrovat sluzby automaticky.

use Contributte\Events\Extra\Event\Application\RequestEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

final class LogRequestSubscriber implements EventSubscriberInterface
{

    public static function getSubscribedEvents(): array
    {
        return [RequestEvent::class => 'onLog'];
    }

    public function onLog(RequestEvent $event): void
    {
        // Do magic..
    }

}
Marek Bartoš
Nette Blogger | 1165
+
+2
-

Eventy velmi snadno vedou ke komplikovaným vazbám a znepřehlednění appky. Pokud se jim můžeš vyhnout nebo je aspoň přesunout do užšího scope (z application do presenteru), tak budeš mít snazší život

Použít event ale samozřejmě můžeš. Nejelegantnější je napojit se na event přes config, pak můžeš debug vypínat zakomentováním jednoho řádku :) V presenteru tak není kód užitečný jen pro debug a v appce globální eventy kvůli jednomu řádku v setupu služby.

services:
	- App\UI\ApplicationDebugger
	application.application:
		setup:
			- '$onShutdown[]' = [@App\UI\ApplicationDebugger, onShutdown]
namespace App\UI;

use Nette\Application\Application;
use Nette\Application\UI\Presenter;

final class ApplicationDebugger
{
	public function onShutdown(Application $application, ?Throwable $throwable): void
	{
		$presenter = $application->getPresenter();
		if ($presenter instanceof Presenter) {
			// ...
		}
	}
}

Editoval Marek Bartoš (16. 1. 2022 13:52)

martin.loucka
Člen | 9
+
0
-

Všem moc díky – nejjednodušší mi přišlo pro ten konkrétní úzký účel si bleskově injectnout Application do Presenteru a vypsat si, co potřebuju.

Ale řešení od @Felix e a @MarekBartoš jsou geniálně krásný, rozhodně využiji na nějakém komplexnějším problému. Díky!

Editoval martin.loucka (16. 1. 2022 15:17)

Milo
Nette Core | 1283
+
0
-

Nebo obecně přímo v PHP https://www.php.net/…function.php