Php 不带控制器的模块的ZF2配置
我目前正在构建一个模块,在多个项目中作为一个可重用的库,但是由于它是一个库,所以不需要控制器。例如,我试图为Marketo soap API创建一个zf2模块。用户在/ROOT/config/autoload/local.php中添加密钥和wsdl位置。配置将包括类似“marketo”=>array()的内容 现在我遇到的问题是我想让我自己和其他使用模块的人能够做一些事情,比如Php 不带控制器的模块的ZF2配置,php,zend-framework2,Php,Zend Framework2,我目前正在构建一个模块,在多个项目中作为一个可重用的库,但是由于它是一个库,所以不需要控制器。例如,我试图为Marketo soap API创建一个zf2模块。用户在/ROOT/config/autoload/local.php中添加密钥和wsdl位置。配置将包括类似“marketo”=>array()的内容 现在我遇到的问题是我想让我自己和其他使用模块的人能够做一些事情,比如 $marketo = new \Marketo\Client\Client(); class Marketo{
$marketo = new \Marketo\Client\Client();
class Marketo{
private $key;
private $pass;
public function __construct(){
$c = \Zend\Config\Config('marketo);
$this->key = $c['key'];
$this->pass = $c['pass'];
}
}
在\Marketo\Client\Client()类中,让构造函数读取$config['Marketo']的数组键
不过,我可以将所有这些都放在一个ini文件中,但我更希望它与zf2中的其他配置类似
所以总结一下,我想得到一个合并zend配置的数组键,以便在类中使用,比如
$marketo = new \Marketo\Client\Client();
class Marketo{
private $key;
private $pass;
public function __construct(){
$c = \Zend\Config\Config('marketo);
$this->key = $c['key'];
$this->pass = $c['pass'];
}
}
===========================根据以下答案,从ZF 2.1.1开始的完整工作解决方案=================
return array(
'service_manager' => array(
'factories' => array(
'Cybersource\Client\Client' => 'Cybersource\ServiceFactory\ClientServiceFactory',
)
),
'cybersource' => array(
'Endpoint' => 'https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor', // test environment
'WSDL' => 'https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor/CyberSourceTransaction_1.80.wsdl',
'TXKey' => '',
'MerchID' => '',
),
);
namespace Cybersource\Client;
class Client {
private $config;
public function __construct($config) {
$this->config = $config;
}
public function getConfig() {
return $this->config;
}
}
namespace Cybersource\ServiceFactory;
use Cybersource\Client\Client;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class ClientServiceFactory implements FactoryInterface {
public function createService(ServiceLocatorInterface $serviceLocator) {
$config = $serviceLocator->get('Config');
return new Client($config['cybersource']);
}
}
namespace Cybersource;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
class Module implements ConfigProviderInterface {
public function getAutoloaderConfig() {
return array(
'Zend\Loader\ClassMapAutoloader' => array(
__DIR__ . '/autoload_classmap.php',
)
);
}
public function getConfig() {
return include __DIR__ . '/config/module.config.php';
}
}
模块结构如下所示(使用一个新示例,以便我可以重新开始)+指示目录名-指示文件名
modules
- Application /* Standard setup with an IndexController */
- Cybersource /* The new module to be added */
+ config
- module.config.php
+ src
+ Cybersource
+ Client
- Client.php
+ ServiceFactory
- ClientServiceFactory.php
- Module.php
- autoload_classmap.php
module.config.php
return array(
'service_manager' => array(
'factories' => array(
'Cybersource\Client\Client' => 'Cybersource\ServiceFactory\ClientServiceFactory',
)
),
'cybersource' => array(
'Endpoint' => 'https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor', // test environment
'WSDL' => 'https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor/CyberSourceTransaction_1.80.wsdl',
'TXKey' => '',
'MerchID' => '',
),
);
namespace Cybersource\Client;
class Client {
private $config;
public function __construct($config) {
$this->config = $config;
}
public function getConfig() {
return $this->config;
}
}
namespace Cybersource\ServiceFactory;
use Cybersource\Client\Client;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class ClientServiceFactory implements FactoryInterface {
public function createService(ServiceLocatorInterface $serviceLocator) {
$config = $serviceLocator->get('Config');
return new Client($config['cybersource']);
}
}
namespace Cybersource;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
class Module implements ConfigProviderInterface {
public function getAutoloaderConfig() {
return array(
'Zend\Loader\ClassMapAutoloader' => array(
__DIR__ . '/autoload_classmap.php',
)
);
}
public function getConfig() {
return include __DIR__ . '/config/module.config.php';
}
}
Client.php
return array(
'service_manager' => array(
'factories' => array(
'Cybersource\Client\Client' => 'Cybersource\ServiceFactory\ClientServiceFactory',
)
),
'cybersource' => array(
'Endpoint' => 'https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor', // test environment
'WSDL' => 'https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor/CyberSourceTransaction_1.80.wsdl',
'TXKey' => '',
'MerchID' => '',
),
);
namespace Cybersource\Client;
class Client {
private $config;
public function __construct($config) {
$this->config = $config;
}
public function getConfig() {
return $this->config;
}
}
namespace Cybersource\ServiceFactory;
use Cybersource\Client\Client;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class ClientServiceFactory implements FactoryInterface {
public function createService(ServiceLocatorInterface $serviceLocator) {
$config = $serviceLocator->get('Config');
return new Client($config['cybersource']);
}
}
namespace Cybersource;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
class Module implements ConfigProviderInterface {
public function getAutoloaderConfig() {
return array(
'Zend\Loader\ClassMapAutoloader' => array(
__DIR__ . '/autoload_classmap.php',
)
);
}
public function getConfig() {
return include __DIR__ . '/config/module.config.php';
}
}
ClientServiceFactory.php
return array(
'service_manager' => array(
'factories' => array(
'Cybersource\Client\Client' => 'Cybersource\ServiceFactory\ClientServiceFactory',
)
),
'cybersource' => array(
'Endpoint' => 'https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor', // test environment
'WSDL' => 'https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor/CyberSourceTransaction_1.80.wsdl',
'TXKey' => '',
'MerchID' => '',
),
);
namespace Cybersource\Client;
class Client {
private $config;
public function __construct($config) {
$this->config = $config;
}
public function getConfig() {
return $this->config;
}
}
namespace Cybersource\ServiceFactory;
use Cybersource\Client\Client;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class ClientServiceFactory implements FactoryInterface {
public function createService(ServiceLocatorInterface $serviceLocator) {
$config = $serviceLocator->get('Config');
return new Client($config['cybersource']);
}
}
namespace Cybersource;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
class Module implements ConfigProviderInterface {
public function getAutoloaderConfig() {
return array(
'Zend\Loader\ClassMapAutoloader' => array(
__DIR__ . '/autoload_classmap.php',
)
);
}
public function getConfig() {
return include __DIR__ . '/config/module.config.php';
}
}
Module.php
return array(
'service_manager' => array(
'factories' => array(
'Cybersource\Client\Client' => 'Cybersource\ServiceFactory\ClientServiceFactory',
)
),
'cybersource' => array(
'Endpoint' => 'https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor', // test environment
'WSDL' => 'https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor/CyberSourceTransaction_1.80.wsdl',
'TXKey' => '',
'MerchID' => '',
),
);
namespace Cybersource\Client;
class Client {
private $config;
public function __construct($config) {
$this->config = $config;
}
public function getConfig() {
return $this->config;
}
}
namespace Cybersource\ServiceFactory;
use Cybersource\Client\Client;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class ClientServiceFactory implements FactoryInterface {
public function createService(ServiceLocatorInterface $serviceLocator) {
$config = $serviceLocator->get('Config');
return new Client($config['cybersource']);
}
}
namespace Cybersource;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
class Module implements ConfigProviderInterface {
public function getAutoloaderConfig() {
return array(
'Zend\Loader\ClassMapAutoloader' => array(
__DIR__ . '/autoload_classmap.php',
)
);
}
public function getConfig() {
return include __DIR__ . '/config/module.config.php';
}
}
自动加载\u classmap.php
return array(
'service_manager' => array(
'factories' => array(
'Cybersource\Client\Client' => 'Cybersource\ServiceFactory\ClientServiceFactory',
)
),
'cybersource' => array(
'Endpoint' => 'https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor', // test environment
'WSDL' => 'https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor/CyberSourceTransaction_1.80.wsdl',
'TXKey' => '',
'MerchID' => '',
),
);
namespace Cybersource\Client;
class Client {
private $config;
public function __construct($config) {
$this->config = $config;
}
public function getConfig() {
return $this->config;
}
}
namespace Cybersource\ServiceFactory;
use Cybersource\Client\Client;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class ClientServiceFactory implements FactoryInterface {
public function createService(ServiceLocatorInterface $serviceLocator) {
$config = $serviceLocator->get('Config');
return new Client($config['cybersource']);
}
}
namespace Cybersource;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
class Module implements ConfigProviderInterface {
public function getAutoloaderConfig() {
return array(
'Zend\Loader\ClassMapAutoloader' => array(
__DIR__ . '/autoload_classmap.php',
)
);
}
public function getConfig() {
return include __DIR__ . '/config/module.config.php';
}
}
<?php
// Generated by ZF2's ./bin/classmap_generator.php
return array(
'Cybersource\Module' => __DIR__ . '/Module.php',
'Cybersource\Client\Client' => __DIR__ . '/src/Cybersource/Client/Client.php',
'Cybersource\ServiceFactory\ClientServiceFactory' => __DIR__ . '/src/ServiceFactory/ClientServiceFactory.php',
);
您应该定义一个服务工厂
来创建您的客户端
。ServiceFactory可以获取合并的模块配置并在客户端上进行设置。您现在有了清晰的分离,您的类甚至可以在没有Zend\Config的情况下重用。
如果有很多配置选项,可以创建一个单独的配置类,扩展\Zend\StdLib\AbstractOptions
,并将其传递给客户端
namespace Marketo\Service;
class ClientServiceFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
//Get the merged config of all modules
$configuration = $serviceLocator->get('Config');
$configuration = $configuration['marketo'];
$client = new \Marketo\Client\Client($configuration['key'], $configuration['pass']);
}
}
现在在服务定位器中注册您的客户端工厂。在module.config.php
或module.php
public function getServiceConfig()
{
return array('factories' => array(
'marketo_client' => 'Marketo\Service\ClientServiceFactory'
);
}
用户现在可以从ServiceManager获取您的客户端。所有配置都已整齐设置
$sm->get('marketo_client');
您可能会定义如下所示的模块:
很抱歉我浪费了你一些宝贵的时间;)呵呵,不需要道歉,如果我在这里,你可以很肯定我还有时间:感谢伟大的回答这是最完整最简单的回答,谢谢@Ocramius。稍后我会更新我的帖子,更新内容与我所做的完全一致,以便让它在这个解决方案的基础上100%正常工作。我在这里没有尝试过的一件事是尝试从另一个非控制器的类中初始化这个类。例如。。。。应用程序\模型\签出。。。。因为我几乎100%确信$c=$this->getServiceLocator()->get('Cybersource\Client\Client');无法在此模块内工作,因为$this上下文在非控制器内没有服务管理器。我将很快尝试并更新我的发现。为您的签出模型创建一个工厂,并将客户端传递给构造函数。与您现在所做的配置相同。或者,您可以让您签出模型ServiceLocatorAware,但我会尽量避免这种情况。@BramGerritsen避免让它成为ServiceLocatorAware的原因是什么?您让您的类依赖于servicelocator,而它确实不应该。以后您无法轻松切换到另一个DI/IOC实现。而且,您无法轻松查看类依赖关系。但这是品味的问题。客户机选项是的,我通常使用getter和setter,但是对于更新的示例,我希望尽可能简单。至于onBootstrap(),它是我忘记删除的初始副本/粘贴,感谢您捕捉到这一点,我以后也会为其他人更新文章。