Zend Expressive,从Php Plates模板获得服务

时间:2016-04-10 09:56:50

标签: php zend-expressive

我使用Zend Expressive framework通过default ZE skeleton app使用Zend ServiceManager作为DIC,使用Plates作为模板引擎。

我们说我有index.phtml模板。我希望得到一些服务,这会转储我的资产,如:

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

服务通过工厂注册并可在应用程序中访问:

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

如何将外部服务实例或其结果传递给模板?

2 个答案:

答案 0 :(得分:1)

将整个服务容器注入模板(或除工厂之外的任何其他类)是非常糟糕的做法。更好的方法是编写一个扩展来转储资产。

扩展类:

<?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();
    }
}

厂:

<?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);
    }
}

配置:

<?php

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

在你的模板中:

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

答案 1 :(得分:0)

我想出了如何通过extensions从模板引擎访问容器。它不清楚MVC-ly,但是......

首先,将plate config添加到config/autoload/templates.global

return [
    // some othe settings    
    'plates' => [
        'extensions' => [
            App\Container\PlatesExtension::class,
        ],
    ],
],

第二步,使用代码

创建App\Container\PlatesExtension.php
<?php

namespace App\Container;

use League\Plates\Engine;
use League\Plates\Extension\ExtensionInterface;

class PlatesExtension implements ExtensionInterface
{
    public $container;

    /**
     * AssetsExtension constructor.
     * @param $container
     */
    public function __construct($container)
    {
        $this->container = $container;
    }

    public function register(Engine $engine)
    {
        $engine->registerFunction('container', [$this, 'getContainer']);
    }

    public function getContainer()
    {
        return $this->container;
    }
}

在第三步,创建工厂App\Container\PlatesExtensionFactory.php以将容器注入板扩展名:

<?php

namespace App\Container;

use Interop\Container\ContainerInterface;

class PlatesExtensionFactory
{
    public function __invoke(ContainerInterface $container)
    {
        return new PlatesExtension($container);
    }
}

接下来,在ServiceManager(config/dependencies.global.php)中注册板块扩展名:

return [
    // some other settings
   'factories' => [
       App\Container\PlatesExtension::class => App\Container\PlatesExtensionFactory::class,
   ]
];

最后,从Plates模板获取容器和所需服务:

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