Search code examples
phpmezzio

Zend Expressive, get service from Php Plates template


I use Zend Expressive framework via default ZE skeleton app with Zend ServiceManager as DIC and Plates as template engine.

Let's say I've got index.phtml template. I want to get some service, which dumps me assets, smth like:

<?= $this->getContainer()->get('my service class')->dumpAssets() ?>

Service is registered via factory and accesible in the app:

<? $container->get('my service class') ?>

How to pass external service instance or its result into template?


Solution

  • It's pretty much bad practice to inject the entire service container into a template (or any other class except a factory). A better approach would be to write an extension to dump the assets.

    Extension class:

    <?php
    
    namespace App\Container;
    
    use League\Plates\Engine;
    use League\Plates\Extension\ExtensionInterface;
    use App\Service\AssetsService;
    
    class DumpAssetsExtension implements ExtensionInterface
    {
        public $assetsService;
    
        /**
         * AssetsExtension constructor.
         * @param $container
         */
        public function __construct(AssetsService $assetsService)
        {
            $this->assetsService = $assetsService;
        }
    
        public function register(Engine $engine)
        {
            $engine->registerFunction('dumpAssets', [$this, 'dumpAssets']);
        }
    
        public function dumpAssets()
        {
            return $this->assetsService->dumpAssets();
        }
    }
    

    Factory:

    <?php
    
    namespace App\Container;
    
    use Interop\Container\ContainerInterface;
    
    class DumpAssetsFactory
    {
        public function __invoke(ContainerInterface $container)
        {
            $assetsService = $container->get(App\Service\AssetsService::class);
    
            return new PlatesExtension($assetsService);
        }
    }
    

    Configuration:

    <?php
    
    return [
        // ...
       'factories' => [
           App\Container\DumpAssetsExtension::class => App\Container\DumpAssetsFactory::class,
       ]
    ];
    

    In your template:

    <?php
        $service = $this->dumpAssets();
    ?>