簡體   English   中英

Zend框架-在控制器內部獲取配置

[英]Zend framework - get config inside controller

我正在使用它來構建zend應用程序。 http://github.com/zendframework/ZendSkeletonApplication

我正在嘗試使用底線獲取放入config/autoload/global.phpconfig/local.php.dist的配置數據,但它會返回

Zend \\ ServiceManager \\ Exception \\ ServiceNotFoundException

並且

在插件管理器Zend \\ Mvc \\ Controller \\ PluginManager中找不到名為“ getServiceLocator”的插件

知道如何獲取配置嗎?

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

目前,使用Zend Framework 3的ZendSkeletonApplication的Master分支。在Zend Framework 3中,控制器中的getServiceLocator()已被刪除。因此,如果要將某些變量從服務傳遞到控制器,則應創建一個工廠。 並在工廠實例化控制器時傳遞變量。

例:

您的控制器名稱是Application Module中的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);
    }
}

應用程序\\控制器\\索引控制器

<?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
        ],
    ],

希望這個幫助

這是為了澄清

ZF3中 ,如果要在應用程序中創建任何需要的類,則使它們可服務,並通過ServiceManager在應用程序中使它們可用。 ServiceManager實現了一個存儲已注冊服務的容器。 那怎么了 ZF使用一種稱為工廠的方法(簡而言之,它創建對象)。 它有助於將服務存儲到容器中。 然后,我們可以使用ServiceManager從該容器中提取服務 讓我們看看如何?

ServiceManager本身就是服務。

因此,使用工廠,使ServiceManager實例在控制器(例如IndexController)中可用。 這樣我們就可以使用它獲得任何服務。

應用程序\\控制器\\ 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);
    }    
}

讓我們注冊IndexControllerFactory的一個工廠的IndexController這樣我們就可以使用它。 module.config.php中進行以下更改

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

一旦由IndexControllerFactory實例化IndexController (通過上述配置), ServiceManager實例就可以通過IndexController的構造函數使用。

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

如果我們需要另一個類而不是控制器中的 config服務中的內容怎么辦? 例如,我們想將圖像上傳到特定的目的地。 那么我們將如何確定上傳路徑? 請參見以下示例。

我們將通過RenameUpload過濾器上傳圖像。 它有一個名為target的選項,用於指定上載路徑的目的地。 讓我們為上傳過濾器創建另一個工廠

應用程序\\控制器\\表格\\過濾器\\上傳過濾器工廠

<?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中 這是用於UploadFilterFactory的

'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',
],

這是Application \\ Form \\ Filter \\ 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 這是為了使對象的分散使用停止。 它刪除了隱藏的依賴項 這使代碼更干凈,更易於理解。 原則是良好的設計

為此,您需要注入配置,因為已經從ZF3中刪除了getServiceLocator(和所有其他定位器)。

在模塊配置中,您需要執行以下操作:

'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;
}

在這里,您可以在類中將配置作為屬性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM