CompilerExtension a „kešování“ v afterCompile()

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
David Grudl
Nette Core | 8112
+
0
-

Funkce CompilerExtension::afterCompile jsou volány v okamžiku, kdy je sestavena PHP třída SystemContainer, kterou reprezentuje objekt ClassType. Je to takové Nette\Utils\Html pro PHP třídy. Než se z něj vygeneruje řetězec a uloží na disk, můžeme do něj zasahovat. Lze třeba přidávat inicializační úkony do metody SystemContainer::initialize. Například spustit všechny služby s tagem run:

	function afterCompile(Nette\Utils\PhpGenerator\ClassType $class)
	{
		foreach ($this->getContainer()->findByTag('run') as $name => $foo) {
			$class->methods['initialize']->addBody('$this->getService(?);', array($name));
		}
	}

Nebo pokud si celý router uložíme do SystemContainer (tj. nekonfigurujeme ho až později v bootstrap.php), můžeme ho „nakešovat“ tak, že sérii volání $router[] = new Route nahradíme serializovaným výsledkem:

	function afterCompile(Nette\Utils\PhpGenerator\ClassType $class)
	{
		$routerMethod = $class->methods['createServiceRouter'];
		$router = eval($routerMethod->body); // tricky
		$routerMethod->setBody('return unserialize(?);', array(serialize($router)));
	}

Ale to je spíš takový trik pro inspiraci ;-) Neměřil jsem, jestli to vůbec něco zrychlí.