【问题标题】:How get basepath from model or helper en Zend Framework 3如何从模型或助手 en Zend Framework 3 中获取基本路径
【发布时间】:2017-07-21 18:56:40
【问题描述】:

在使用 Zend Framework 1 3 年后,我最近决定使用 Zend Framework 3。这个决定让我很头疼,Zend 3 并没有让事情变得更容易,反而让事情变得更加困难。

在 Zend 1 中,我在数据库中自定义了所选模板的 url,如下所示:

public function getUrl(string $file = '')
{
    if($this->_helperBaseUrl === null) {
        $this->_helperBaseUrl = new Zend_View_Helper_BaseUrl();
    }
    return $this->_helperBaseUrl->baseUrl($file);
}

public function getSkinUrl(string $file = '')
{
    $themePath = 'themes/my-theme/'; //get from database
    return $this->getUrl($themePath . ltrim($file, '/\\'));
}

然后在应用程序的任何部分(模型、助手、插件和视图)我都可以像这样访问这个函数:

//view/scripts/index/index.phtml
$url_logo = My::app()->getSkinUrl('logo.jpg');
//this return http://example.com/themes/my-theme/logo.jpg

在 Zend 3 中,这对我来说非常困难。有人知道在 Zend 3 中有什么方法吗?或者如何从 Zend 3 中的模型中获取 baseUrl?

【问题讨论】:

  • 你迟到了 5 年 :)
  • @tasmaniski 3 年前我使用的是 ZF2,但它比 ZF1 慢。因此,我继续使用 ZF1 :)

标签: zend-framework zend-framework2 zend-framework3


【解决方案1】:

在 Zend Framework 2/3 中,您几乎可以将任何类注入到另一个中。例如,如果您需要 basePath 插件(在视图上下文中可用),您可以将此插件注入您的模型/服务或控制器类。这是推荐的方式:

这是您需要此插件或任何其他服务的类

use Zend\View\Helper\BasePath;

class MyService
{
    /**
     * @var BasePath
     */
    protected $plugin;

    /**
     * MyService constructor.
     *
     * @param BasePath $basePath
     */
    public function __construct(BasePath $basePath)
    {
        $this->plugin = $basePath;
    }

    /**
     * @return BasePath
     */
    public function getPlugin()
    {
        return $this->plugin;
    }

    /**
     * @param BasePath $plugin
     */
    public function setPlugin($plugin)
    {
        $this->plugin = $plugin;
    }
}

现在,您需要工厂将一个依赖项注入另一个依赖项

use Interop\Container\ContainerInterface;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use MyNamespace\Service\MyService;

class MyServiceFactory implements FactoryInterface
{
    /**
     *
     * @param ContainerInterface $container
     * @param string $requestedName
     * @param null|array $options
     * @return MyService
     */
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        $class = $requestedName ? $requestedName : MyService::class;
        $plugin = $container->get('ViewHelperManager')->get('BasePath'); // inject this class
        $myService = new $class($plugin); // into this class

        return $myService;

    }
    /**
     * Provided for backwards compatibility; proxies to __invoke().
     *
     * @param ContainerInterface|ServiceLocatorInterface $container
     * @return MyService
     */
    public function createService(ServiceLocatorInterface $container)
    {
        return $this($container, MyService::class);
    }
}

好的,现在MyServicebasePath 插件,但是要在控制器中使用它,您必须将服务注入控制器。所以...

索引控制器

use MyNamespace\Service\MyService;
use Zend\Mvc\Controller\AbstractActionController;

class IndexController extends AbstractActionController
{
    /**
     * @var MyService
     */
    protected $service;

    /**
     * IndexController constructor.
     * 
     * @param MyService $service
     */
    public function __construct(MyService $service)
    {
        $this->service = $service;
    }

    public function indexAction()
    {
        $plugin = $this->service->getPlugin(); // Zend\View\Helper\BasePath object
        //...
    }
}

...以及我们控制器的工厂...

use Interop\Container\ContainerInterface;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use MyNamespace\Controller\IndexController;

class IndexControllerFactory implements FactoryInterface
{
    /**
     *
     * @param ContainerInterface $container
     * @param string $requestedName
     * @param null|array $options
     * @return IndexController
     */
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        $class = $requestedName ? $requestedName : IndexController::class;
        $myService = $container->getServiceLocator()->get('MyNamespace\Service\MyService');
        $controller = new $class($myService);

        return $controller;

    }
    /**
     * Provided for backwards compatibility; proxies to __invoke().
     *
     * @param ContainerInterface|ServiceLocatorInterface $container
     * @return IndexController
     */
    public function createService(ServiceLocatorInterface $container)
    {
        return $this($container, IndexController::class);
    }
}

快完成了。最后一步是在module.config.php文件中设置配置

use MyNamespace\Controller;
use MyNamespace\Factory;

return [
    //...
    'service_manager' => [
        'factories' => [
            Service\MyService::class => Factory\Service\MyServiceFactory::class
        ]
    ],
    'controllers' => [
        'factories' => [
            Controller\IndexController::class => Factory\Controller\IndexControllerFactory::class
        ],
    ],
]

很简单,不是吗?
如果您需要控制器中的插件,而不是模型/服务类中的插件,您可以跳过此“教程”的MyService 部分并将插件直接注入控制器类

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-20
    • 2011-07-15
    • 1970-01-01
    • 2011-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多