ZF2从模块加载服务配置 [英] ZF2 load service config from module
问题描述
我想实现:
实例化+调用ZF2服务方法外部ZF通过使用ServiceManager和可能的DI。
我现在所在:(更新4/10/2013 )
跟进下面的评论,我做了更多的研究,特别是:
- 快速指南
http://framework.zend.com/manual/2.0/en/modules/zend.service-manager.quick-start.html - RTD(数据库和模型)http:
//zf2.readthedocs.org/en/latest/user-guide/database-and-models.html - 模块演示文稿(非常有帮助) http://www.youtube.com/watch?v= Vp7y65rnN98#t = 1200
- github上的模块源 - https://github.com/juriansluiman/SlmMa il
我已经选择修剪所有DI和ModuleManager的东西,并尝试自动加载(现在正常工作)和实例化
1 - 使用Classmap自动加载所请求的类,并在独立的.PHP文件中实例化服务器
//通过classmap
自动加载ZF和ProductImage模块Zend \Loader \\ \\AutoloaderFactory :: factory(array(
'Zend\Loader\StandardAutoloader'=>数组(
'autoregister_zf'=> TRUE,
),
'Zend\Loader\ClassMapAutoloader'=>数组(
'/home/frequency/domains/scrftcdn/public_html/ft/shop/php/zendframework/module/ProductImage/autoload_classmap.php',
)
)
)
//硬编码的servicemanager配置(将从$ module-> getConfig一次工作)
$ smc = new \Zend\ServiceManager\Config(
数组(
'service_manager'=>数组(
'工厂'=>数组(
'ProductImage\Model\ProductImage'=>'ProductImage\Factory\ ProductImageFactory',
)
),
)
);
//实例化服务管理器
$ sm = new \Zend\ServiceManager\ServiceManager($ smc);
//通过服务管理器加载服务
$ service = $ sm-> get('ProductImage\Model\ProductImage'); //< throws exception
die();
2 - 例外
[error] [客户端192.168.6.52] PHP致命错误:
未捕获的异常'Zend\\ServiceManager\\Exception\\\ServiceNotFoundException '消息'Zend\\\ServiceManager\\ServiceManager :: get无法在/ usr / lib / zendframework / library / Zend中获取或创建ProductImage \\Model\\\ProductImage的实例/ServiceManager/ServiceManager.php:495
堆栈跟踪:\\\
#0 /home/frequency/domains/wpfreqad/public_html/wp-content/themes/frequency/manage-product-images/functions.inc.php (48):Zend\\\ServiceManager\\\ServiceManager-> get('ProductImage\\Mo ...')
#1 / home / frequency / domains / wpfreqad / public_html / wp -content / themes / frequency / functions.inc.php(14):require_once('/ home / frequency ...')\\\
#2 / home / frequency / domains / wpfreqad / public_html / wp-内容/主题/ F requency / functions.php(14):require_once('/ home / frequency ...')\\\
#3 /home/frequency/domains/wpfreqad/public_html/wp-settings.php(293): include('/ home / frequency ...')\\\
#4 /home/frequency/domains/wpfreqad/public_html/wp-config.php(90):require_once('/ home / frequency .. 。')\\\
#5 /home/frequency/domains/wpfreqad/public_html/wp-load.php(29):require_onc in /usr/lib/zendframework/library/Zend/ServiceManager/ServiceManager.php在线495
3 - ProductImage\autoload_classmap.php
<?php
//由ZF2的./bin/classmap_generator.php生成
返回数组(
'ProductImageTest\Service\ProductImageServiceTest'=> __DIR__。 '/test/ProductImageTest/Service/ProductImageServiceTest.php',
'ProductImage\Module'=> __DIR__。 '/Module.php',
'ProductImage\Factory\ProductImageFactory'=> __DIR__。 '/src/ProductImage/Factory/ProductImageFactory.php',
'ProductImage\Model\ProductImage'=> __DIR__。 '/src/ProductImage/Model/ProductImage.php',
);
4 - ProductImage\Module.php
类模块实现\Zend\ModuleManager\Feature\ConfigProviderInterface
{
/ *由模块管理器* /
public function getConfig()
{
return include __DIR__。 /config/module.config.php;
}
}
5 - ProductImage\config\ module.config.php
<?php
return array(
'service_manager '=>数组(
'工厂'=>数组(
'ProductImage\Model\ProductImage'=>'ProductImage\Factory\ProductImageFactory',
)
),
);
我希望这是正确的方法,不要太过于正确的方式..
我终于找到了一个解决方案。茱莉安的使用实际应用的提示让我走上正轨! :)
1 - /zendframework/config/application.config.php。
一切都是默认的,只需确保添加模块。我评论了'应用程序'模块,因为我没有看到任何使用(现在)。我也不得不将配置文件的路径从'./ module'
更改为 __ DIR__。 '../ module'
因为它在错误的目录(花了我一段时间找到那个)。
<?php
返回数组(
// ...
'modules'=>数组(
'ProductImage',/ * ProductImage模块* /
//'Application',
),
// ...
'module_listener_options'=>数组(
'module_paths'=>数组(
__DIR__。'/../module',
__DIR__。'/../vendor',
),
2 - 配置
确保模块配置正确, ZF2路径设置正确,在我的情况下,快速启动RTD( http://zf2.readthedocs.org/en/latest/ref/installation.html ),我有 ZF2_PATH
异常并更改 httpd.conf
通过WHM。
3 - 阅读更多关于RTD
特别是关于如何引导应用程序: http://zf2.readthedocs.org/en/latest/modules/zend.mvc.intro.html#zend-mvc -intro
其中经过很少的调试后,我产生了以下代码来访问整齐配置的$ sm实例。
// ZF2应用程序框架在哪里,包括autoloader
require_once'/home/path/to/the/ZF2/application/directory/init_autoloader.php ;
使用Zend\Loader\AutoloaderFactory;
使用Zend\Mvc\Application;
使用Zend\Mvc\Service\ServiceManagerConfig;
使用Zend\ServiceManager\ServiceManager;
// setup autoloader
AutoloaderFactory :: factory();
//获取应用程序堆栈配置
$ configuration = include'/home/path/to/the/ZF2/application/directory/config/application.config.php';
// var_export($ configuration);
// init()方法与前面的例子非常相似。
$ app = Application :: init($ configuration);
$ sm = $ app-> getServiceManager();
$ pi = $ sm-> get('ProductImage\Service\ProductImageService');
var_export($ pi);
die();
我不喜欢除了init_autoloader路径之外还需要指定配置。我避免将这个实现复制和粘贴在整个地方,我正在考虑将 $ sm
实例化集成到 init_autoloader.php
,以便每当需要调用 ProductImage
服务时,不需要指定配置文件的路径。
I am still struggling in instantiating a service from a ZF2 module outside of Zend Framework (in a blank .php).
I want to achieve:
Instantiate + invoke a ZF2 service method from outside ZF by the use of the ServiceManager and possibly DI.
What I have now: (UPDATED 4/10/2013)
Following up on the comments below I have done more research,particularly:
- The quick guide
http://framework.zend.com/manual/2.0/en/modules/zend.service-manager.quick-start.html - RTD (Databases and models) http:
//zf2.readthedocs.org/en/latest/user-guide/database-and-models.html - Modules presentation (Very helpful) http://www.youtube.com/watch?v=Vp7y65rnN98#t=1200
- Module source on github - https: //github.com/juriansluiman/SlmMail
I've opted to trim out all the DI and ModuleManager things and try to autoload (works fine now) and instantiate (does not) a service.
1 - Autoload the requested classes using a Classmap and instantiate servicemanager in a stand-alone .PHP file
// Autoload ZF and ProductImage module via classmap
Zend\Loader\AutoloaderFactory::factory(array(
'Zend\Loader\StandardAutoloader' => array(
'autoregister_zf' => TRUE,
),
'Zend\Loader\ClassMapAutoloader' => array(
'/home/frequency/domains/scrftcdn/public_html/ft/shop/php/zendframework/module/ProductImage/autoload_classmap.php',
)
)
)
// Hard-coded servicemanager configuration (will come from $module->getConfig once this works)
$smc = new \Zend\ServiceManager\Config(
array(
'service_manager' => array(
'factories' => array(
'ProductImage\Model\ProductImage' => 'ProductImage\Factory\ProductImageFactory',
)
),
)
);
// Instantiate the service manager
$sm = new \Zend\ServiceManager\ServiceManager($smc);
//Load the service via the service manager
$service = $sm->get('ProductImage\Model\ProductImage'); // <throws exception
die();
2 - The exception
[error] [client 192.168.6.52] PHP Fatal error:
Uncaught exception 'Zend\\ServiceManager\\Exception\\ServiceNotFoundException' with message 'Zend\\ServiceManager\\ServiceManager::get was unable to fetch or create an instance for ProductImage\\Model\\ProductImage' in /usr/lib/zendframework/library/Zend/ServiceManager/ServiceManager.php:495
Stack trace:\n#0 /home/frequency/domains/wpfreqad/public_html/wp-content/themes/frequency/manage-product-images/functions.inc.php(48): Zend\\ServiceManager\\ServiceManager->get('ProductImage\\Mo...')
#1 /home/frequency/domains/wpfreqad/public_html/wp-content/themes/frequency/functions.inc.php(14): require_once('/home/frequency...')\n
#2 /home/frequency/domains/wpfreqad/public_html/wp-content/themes/frequency/functions.php(14): require_once('/home/frequency...')\n
#3 /home/frequency/domains/wpfreqad/public_html/wp-settings.php(293): include('/home/frequency...')\n
#4 /home/frequency/domains/wpfreqad/public_html/wp-config.php(90): require_once('/home/frequency...')\n
#5 /home/frequency/domains/wpfreqad/public_html/wp-load.php(29): require_onc in /usr/lib/zendframework/library/Zend/ServiceManager/ServiceManager.php on line 495
3 - ProductImage\autoload_classmap.php
<?php
// Generated by ZF2's ./bin/classmap_generator.php
return array(
'ProductImageTest\Service\ProductImageServiceTest' => __DIR__ . '/test/ProductImageTest/Service/ProductImageServiceTest.php',
'ProductImage\Module' => __DIR__ . '/Module.php',
'ProductImage\Factory\ProductImageFactory' => __DIR__ . '/src/ProductImage/Factory/ProductImageFactory.php',
'ProductImage\Model\ProductImage' => __DIR__ . '/src/ProductImage/Model/ProductImage.php',
);
4 - ProductImage\Module.php
class Module implements \Zend\ModuleManager\Feature\ConfigProviderInterface
{
/* Invoked by Module Manager */
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
}
5 - ProductImage\config\module.config.php
<?php
return array(
'service_manager' => array(
'factories' => array(
'ProductImage\Model\ProductImage' => 'ProductImage\Factory\ProductImageFactory',
),
),
);
I hope that's the right approach and not too far off the right way..
I've finally found a solution. Jurian's hints to using the actual application have put me on the right track! :)
1 - /zendframework/config/application.config.php.
Everything is default, just make sure the module is added. I commented the 'application' module as I don't see any use for it (as of now). I also had to change the path to the config files from './module'
to __DIR__ . '../module'
as it was looking in the wrong directory (took me a while to find that one).
<?php
return array(
// ...
'modules' => array(
'ProductImage', /* ProductImage module */
// 'Application',
),
// ...
'module_listener_options' => array(
'module_paths' => array(
__DIR__ . '/../module',
__DIR__ . '/../vendor',
),
2 - configuration
make sure the modules are configured right, and also that ZF2 Path is set up correctly. In my case, run through the quick start on RTD (http://zf2.readthedocs.org/en/latest/ref/installation.html). I had the ZF2_PATH
exception and change the httpd.conf
via WHM.
3 - Read more on RTD
In particular on how you can bootstrap the application: http://zf2.readthedocs.org/en/latest/modules/zend.mvc.intro.html#zend-mvc-intro
Which after very little debugging produced me the following code to access a neatly configured $sm instance.
//wherever the ZF2 application skeleton is, include the autoloader
require_once '/home/path/to/the/ZF2/application/directory/init_autoloader.php';
use Zend\Loader\AutoloaderFactory;
use Zend\Mvc\Application;
use Zend\Mvc\Service\ServiceManagerConfig;
use Zend\ServiceManager\ServiceManager;
// setup autoloader
AutoloaderFactory::factory();
// get application stack configuration
$configuration = include '/home/path/to/the/ZF2/application/directory/config/application.config.php';
//var_export($configuration);
// The init() method does something very similar with the previous example.
$app = Application::init($configuration);
$sm = $app->getServiceManager();
$pi = $sm->get('ProductImage\Service\ProductImageService');
var_export($pi);
die();
I do not like the fact that the configuration needs to be specified in addition to the init_autoloader path. I avoid this implementation from being copied and pasted all over the place, I am considering integrating the $sm
instantiation into the init_autoloader.php
in the future so that the path of the configuration file does not have to be specified whenever a ProductImage
service needs to be invoked.
这篇关于ZF2从模块加载服务配置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!