2017-03-02 80 views
0

我最近決定在使用Zend Framework 1 3年後使用Zend Framework 3。這個決定令我頭痛,Zend 3讓事情變得更簡單,使事情變得更加困難。如何從模型或助手中獲取basepath Zend Framework 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?

+0

你只遲到了5年:) – tasmaniski

+0

@ tasmaniski 3年前我使用ZF2,但它比ZF1慢。出於這個原因,我繼續使用ZF1 :) –

回答

2

在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插件,但要在控制器中使用它,您必須將您的服務注入控制器。所以......

的IndexController

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一部分,並直接注入到插件控制器類

相關問題