我正在使用它来构建zend应用程序。 http://github.com/zendframework/ZendSkeletonApplication
我正在尝试将我放在config/autoload/global.php
和config/local.php.dist
内的配置数据与底线对齐,但它会返回
的Zend \的ServiceManager \异常\ ServiceNotFoundException的
以及
在插件管理器Zend \ Mvc \ Controller \ PluginManager中找不到名为“getServiceLocator”的插件
知道如何获得配置吗?
$config = $this->getServiceLocator()->get('config');
答案 0 :(得分:4)
目前ZendSkeletonApplication的主分支使用Zend Framework 3.控制器中的getServiceLocator()
已remove in Zend Framework 3.
所以,如果你想将一些变量从服务传递给控制器,你应该创建一个工厂。并在工厂中实例化控制器时传递变量。
示例:强>
您的控制器名称来自IndexController
模块的Application
。工厂类是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
],
],
希望这个帮助
答案 1 :(得分:3)
这是为了澄清
在 ZF3 中,如果要在应用程序中创建任何需要的类,请将它们设为可维护,通过 ServiceManager 在应用程序中使它们可用。 ServiceManager 实现了一个存储已注册服务的容器。那是怎么回事? ZF使用一种名为 factory 的方法(简而言之,它创建了对象)。它有助于将服务存储到容器中。然后,我们可以使用 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,
],
],
IndexController 由 IndexControllerFactory (通过上述配置)实例化后, 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 的选项,用于指定上载路径的目标。让我们为上传过滤器创建另一个工厂。
<强>应用\控制器\表格\筛选\ 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 中。这适用于 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 ?这是为了使对象的分散使用停止。它会删除隐藏的依赖项。这使代码更干净,更容易理解。原则是 好设计 。
答案 2 :(得分: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;
}
在这里,您可以在课堂上使用您的配置作为属性。