0

Zend Framework の外部 (空白の .php) で ZF2 モジュールからサービスをインスタンス化するのにまだ苦労しています。

私は達成したい:

ServiceManager と場合によっては DI を使用して、ZF の外部から ZF2 サービス メソッドをインスタンス化 + 呼び出します。

私が今持っているもの:( 2013年4月10日更新

以下のコメントをフォローアップして、特に以下の調査を行いました。

私はすべての DI と ModuleManager のものを取り除き、サービスを自動ロード (現在は正常に動作) し、インスタンス化 (しない) することを選択しました。

1 - Classmap を使用して要求されたクラスを自動ロードし、スタンドアロンの .PHP ファイルで servicemanager をインスタンス化します。

// 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',
        ),
    ),
);

それが正しいアプローチであり、正しい方法から遠く離れていないことを願っています..

4

1 に答える 1

2

私はついに解決策を見つけました。実際のアプリケーションを使用するためのジュリアンのヒントは、私を正しい軌道に乗せました! :)

1 - /zendframework/config/application.config.php。

すべてがデフォルトです。モジュールが追加されていることを確認してください。「アプリケーション」モジュールにコメントしましたが、(今のところ) 用途が見当たらないからです。また、間違ったディレクトリを探していたため、構成ファイルへのパスを から に変更する必要があり'./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 パスが正しく設定されていることを確認してください。私の場合、RTD のクイック スタート ( http://zf2.readthedocs.org/en/latest/ref/installation.html ) を実行します。ZF2_PATH例外があり、via httpd.confWHM を変更しました。

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 パスに加えて構成を指定する必要があるという事実は気に入りません。この実装をあちこちにコピー アンド ペーストすることは避けます。サービスを呼び出す必要があるたびに構成ファイルのパスを指定する必要がないように、将来的に$smインスタンス化を に統合することを検討しています。init_autoloader.phpProductImage

于 2013-10-05T16:34:55.380 に答える