2017-04-17 96 views
0

我正在使用它来构建zend应用程序。 http://github.com/zendframework/ZendSkeletonApplicationZend框架 - 获取控制器内的配置

我试图让我把config/autoload/global.phpconfig/local.php.dist与底线里面的配置数据,但它返回

Zend\ServiceManager\Exception\ServiceNotFoundException

A plugin by the name "getServiceLocator" was not found in the plugin manager Zend\Mvc\Controller\PluginManager

任何想法如何,我可以得到配置?

$config = $this->getServiceLocator()->get('config'); 

回答

0

为了做到这一点,你需要注入的配置,因为getServiceLocator(和所有其他定位器)已经从ZF3删除。

在你的模块配置你有这样的:

'controllers' => [ 
    'factories' => [ 
     Controller\IndexController::class => InvokableFactory::class, 
    ], 
], 

你可以改变工厂创建你自己的。

Controller\IndexController::class => Controller\IndexControllerFactory::class, 

下面的代码:

final class IndexControllerFactory 
{ 
    public function __invoke(Container $container) : IndexController 
    { 
     $config = $container->get('config'); 
     if (!isset($config['stuff']['stuff']) { 
      throw new \Exception('Please add the stuff.stuff parameter in the config'); 
     } 
     $myParam = $config['stuff']['stuff']; 
     return new IndexController($myParam); 
    } 
} 

Container是PSR容器。

在你的控制器中添加一个构造函数接收你所需要的配置:

public function __construct(string $param) 
{ 
    $this->param = $param; 
} 

在这里,你必须在你的类的配置,作为一个属性。

+0

嗨,我有以下,但有错误: – sparkmix

0

在控制器使用Zend Framework 3.与getServiceLocator()的时刻ZendSkeletonApplication主分支已经remove in Zend Framework 3. 所以,如果你想从服务传递一些变量控制器,你应该建立一个工厂。在工厂实例化控制器时传递变量。

实施例:

你的控制器名称是从Application模块IndexController。工厂类是IndexControllerFactory

应用\控制器\ IndexControllerFactory

<?php 
namespace Application\Controller; 

use Zend\ServiceManager\Factory\FactoryInterface; 
use Interop\Container\ContainerInterface; 

class IndexControllerFactory implements FactoryInterface 
{ 
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null) 
    { 
     $config = $container->get("Config"); 
     return new IndexController($config); 
    } 
} 

应用\控制器\的IndexController

<?php 
namespace Application\Controller; 

use Zend\Mvc\Controller\AbstractActionController; 

class IndexController extends AbstractActionController 
{ 
    private $config; 

    public function __construct(array $config) 
    { 
     $this->config = $config; 
    } 

    public function indexAction() 
    { 
     // use $this->config here 
    } 
} 

和这里在module.config.php

'controllers' => [ 
     'factories' => [ 
      Controller\IndexController::class => Controller\IndexControllerFactory::class 
     ], 
    ], 
配置

希望这有助于

+0

不工作。 –

0

这是澄清

ZF3,如果要创建需要在应用程序中的任何类,让他们维修,让他们通过的ServiceManager在应用程序中使用。 ServiceManager实现了一个存储注册服务的容器。那是怎么回事?采埃孚使用一种名为的工厂(简而言之,它创建了对象)。它有助于将服务存储到容器中。然后,我们可以使用ServiceManager从该容器中提取服务。让我们看看如何?

ServiceManager本身就是一项服务。

所以使用工厂让我们在控制器可用的ServiceManager实例(例如,索引控制器)。这样我们就可以使用它来获得任何服务。

应用\控制器\ IndexControllerFactory

<?php 
namespace Application\Controller; 

// This is the container 
use Interop\Container\ContainerInterface; 
use Zend\ServiceManager\Factory\FactoryInterface; 

class IndexControllerFactory implements FactoryInterface 
{ 
    public function __invoke(ContainerInterface $container, $requestedName, array $options = NULL) 
    { 
     $serviceManager = $container->get('ServiceManager'); 
     return new IndexController($serviceManager); 
    }  
} 

让我们来配置它,使我们可以使用它。请在moudle.config.php

'controllers' => [ 
    'factories' => [ 
     Controller\IndexController::class => Controller\IndexControllerFactory::class, 
    ], 
], 

一旦的IndexController通过IndexControllerFactory实例如下变化(通过以上配置)的的ServiceManager例如,通过索引控制器的构造变得可用。

<?php 
namespace Application\Controller; 

use Zend\Mvc\Controller\AbstractActionController; 
use Zend\View\Model\ViewModel; 
use Zend\ServiceManager\ServiceManager; 

class IndexController extends AbstractActionController 
{ 
    protected $serviceManager; 

    public function __construct(ServiceManager $serviceManager) 
    { 
     // Here we set the service manager instance 
     $this->serviceManager = $serviceManager; 
    } 

    public function indexAction() 
    { 
     // Use this as you want 
     $config = $this->serviceManager->get('config'); 

     return new ViewModel(); 
    } 

如果我们需要另一个类,而不是控制器内从配置服务的东西是什么?例如,我们想要将图像上传到特定的目的地。那么我们如何解决上传路径?看下面的例子。

我们将通过上载图片RenameUpload过滤器。它有一个选项,名称为目标它指定上载路径的目的地。我们为上传过滤器创建另一个工厂

应用\控制器\表格\过滤器\ UploadFilterFactory

<?php 
namespace Application\Form\Filter; 

use Interop\Container\ContainerInterface; 
use Zend\ServiceManager\Factory\FactoryInterface; 
use Application\Form\Filter\UploadFilter; 

class UploadFilterFactory implements FactoryInterface 
{ 

    public function __invoke(ContainerInterface $container, $requestedName, array $options = NULL) 
    { 
     $config = $container->get('config'); 

     // Look! here we fix the upload path 
     $uploadPath = $config['module_config']['upload_path']; 

     // Here we're injecting that path 
     return new UploadFilter($uploadPath); 
    } 
} 

做同样的UploadForm,如果你需要。这将是UploadFormFactory

把下面的两个片段在module.config.php。这是为上传过滤器工厂

'service_manager' => [ 
    'factories' => [ 
     // UploadForm::class => UploadFormFactory::class, 
     UploadFilter::class => UploadFilterFactory::class, 
    ], 

    // Make an alias so that we can use it where we need 
    // it could be uploadAction() inside any controller 
    // $inputForm = $this->serviceManager->get('UploadForm'); 
    // $inputFilter = $this->serviceManager->get('UploadFilter'); 
    // $uploadForm->setInputFilter($inputFilter), for example 
    'aliases' => [ 
     // 'UploadForm' => UploadForm::class, 
     'UploadFilter' => UploadFilter::class, 
    ], 
], 

,这一次为上传路径,无论你想上传。

'module_config' => [ 
    // Set the path as you want 
    'upload_path' => __DIR__ . '/../data/upload', 
], 

这是申请\表格\过滤器\ UploadFilter

<?php 
namespace Application\Form\Filter; 

use Zend\InputFilter\InputFilter; 
use Zend\Filter\File\RenameUpload; 

class UploadFilter extends InputFilter 
{ 
    protected $uploadPath; 

    public function __construct(string $uploadPath) 
    { 
     // We're assigning here so that we can use it 
     // on the filter section. 
     $this->uploadPath = $uploadPath; 

     $this->prepareFilters(); 
    } 

    public function prepareFilters() 
    { 
     $this->add(array(
      'name' => 'image', 
      'required' => true, 
      'filters' => array(
       array(
        'name' => RenameUpload::class, 
        'options' => array(
         // Thus here we use it 
         'target' => $this->uploadPath, 
         'overwrite' => true, 
         'randomize' => true, 
         'use_upload_extension' => true, 
        ),   
       ), 
      ), 
      'validators' => array(), 
     )); 
    } 
} 

这是使事情变得有用的一种方法。那么为什么ServiceManager?这是为了使分散的对象停止使用。它删除隐藏的依赖关系。这使得代码更简洁易懂。原则是好设计