Я все еще пытаюсь создать экземпляр службы из модуля ZF2 вне Zend Framework (в пустой .php).
Я хочу достичь:
Мгновенное действие + вызов метода службы ZF2 извне ZF с помощью ServiceManager и, возможно, DI.
Что у меня есть сейчас: ( ОБНОВЛЕНО 4/10/2013 )
Следуя приведенным ниже комментариям, я сделал больше исследований, в частности:
Я решил обрезать все объекты DI и ModuleManager и попытаться выполнить автозагрузку (теперь работает отлично) и создать экземпляр (не) сервис.
1 – Автозагрузка запрошенных классов с использованием Classmap и создание экземпляра servicemanager в автономном файле .PHP
// 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 – Исключение
[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', ), ), );
Надеюсь, это правильный подход и не слишком далеко.
Я наконец нашел решение. Советы Юриана по использованию реального приложения поставили меня на правильный путь! 🙂
1 – /zendframework/config/application.config.php.
Все по умолчанию, просто убедитесь, что модуль добавлен. Я прокомментировал модуль «приложение», поскольку я не вижу для него никакого использования (на данный момент). Мне также пришлось изменить путь к конфигурационным файлам из './module'
в __DIR__ . '../module'
__DIR__ . '../module'
поскольку он искал неправильный каталог (мне понадобилось некоторое время, чтобы найти его).
<?php return array( // ... 'modules' => array( 'ProductImage', /* ProductImage module */ // 'Application', ), // ... 'module_listener_options' => array( 'module_paths' => array( __DIR__ . '/../module', __DIR__ . '/../vendor', ),
2 – конфигурация
убедитесь, что модули настроены правильно, а также что ZF2 Path настроен правильно. В моем случае запустите быстрый запуск в 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.
//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();
Мне не нравится тот факт, что конфигурация должна быть указана в дополнение к пути init_autoloader. Я не init_autoloader.php
чтобы эта реализация была скопирована и вставлена повсюду, я рассматриваю возможность интеграции экземпляра $sm
в init_autoloader.php
в будущем, так что путь к файлу конфигурации не должен указываться всякий раз, когда службе ProductImage
необходимо вызывается.