6

Zend Framework 1 の長年の開発者として、Zend Framework 2 の学習を始めたばかりです。新しい用語に頭を悩ませています。

ZF1 に戻って、アプリケーションに対してグローバルなロガーを作成したい場合は、構成を application.ini ファイルに追加し、ブートストラップがそれをリソースとして初期化します (私がそう言っていることを願っています)。そのため、どのモジュール コントローラーからでも、ブートストラップ リソースを介してロガーにアクセスできました。

ZF2 に入ります。モジュールは少し異なります。自己完結型ですが、アプリケーションとの対話方法について少し混乱しています。これが ServiceManager の出番だと私には思えます。私の目標は、モジュール (コントローラーではなくモジュール自体) を用意し、アプリケーションがロガーを定義しているかどうかを確認し、定義されている場合はモジュール全体でそのロガーを利用することです。アプリケーションでロガーが定義されていない場合、モジュール全体のログ記録用にモジュールでロガーを定義する必要があります。

この質問はデータベースにも関連しています。たとえば、アプリケーションでデータベース接続のロジックを定義し、モジュールで必要なテーブルのロジックを定義したいとします。これをどのように正確に構成するのですか? また、アプリケーションでデータベース リソースが既に定義されているかどうかをどのように/どこで確認できますか?

注: 私は、Rob Allen のクイックスタート (非常に多くの情報と、これまでのところあいまいさを欠いていることがわかった唯一のリソース) と ZF2 (readthedocs) を調べ、すでにトンをググりました。私が見つけたのは、パズルの特定のピースが「どこに」行くかということになると、一般的に情報が非常に曖昧であるということです.

4

2 に答える 2

6

Zend Framework 1.x からわかることは、「アプリケーション リソース」です。

「アプリケーション リソース」の概念は、Zend Framework 2 ではいわゆる「サービス」に置き換えられました(イントロはこちら) 。

もう 1 つの変更点は、モジュール自体です。ZF1 では、モジュールは主に、一部の要求を処理するアプリケーションのサブセクションでした。これは ZF2 では当てはまりません。モジュールがサービスまたはコントローラーを定義している場合、そのサービスまたはコントローラーはすべてのアプリケーションからアクセスできるようになりました。Gary Hockin による ZF1 と ZF2 のいくつかの違いについての紹介があります。

とにかく、モジュールは自己完結型ではありません。それらは隔離された環境で開発し、依存関係をできるだけ少なくする必要がありますが、すべてのアプリケーションに影響を与える相互懸念機能を提供します。

ロガーの特定のケースについては、モジュールで常にロガーを定義して使用することをお勧めします。条件付きでロガーを定義するために実行できることは次のとおりです。

class MyModule
{
    public function onBootstrap($e)
    {
        // $e->getTarget() is the \Zend\Mvc\Application
        $sm = $e->getTarget()->getServiceManager();

        if (!$sm->has('some-logger-name')) {
            $sm->setFactory('some-logger-name', function ($sl) {
                return new MyLogger($sl->get('some-db'));
            });
        }
    }
}

その後、すべてのアプリケーションで「some-logger-name」を使用できます。

別のアプローチは、単にロガー サービスを定義し、後で他のモジュールまたは構成でオーバーライドできるようにすることです。

class MyModule
{
    public function getConfig()
    {
        return array(
            'service_manager' => array(
                'factories' => array(
                    'some-logger-name' => 'My\Logger\Factory\ClassName'
                ),
            ),
        );
    }
}

これは柔軟getServiceConfig性が低く、キャッシュできませんが、getConfig(オーバーライドを許可する) より優先度が高く、サービス ファクトリをクロージャーとして定義することもできます。

class MyModule
{
    public function getServiceConfig()
    {
        return array(
            'factories' => array(
                'some-logger-name' => function ($sl) {
                    return new MyLogger($sl->get('some-db'));
                },
            ),
        );
    }
}

次に、使用するロガー (サービス名) を決定するために使用する必要がある構成キーを定義することもできます。

モジュールと構成の概念は、「最後のモジュールが勝つ」というものであるため'some-logger-name'、モジュールまたはその前にロードされたモジュールでサービスを定義できます。

同じ概念が DB 接続にも適用されます。

ご覧のとおり、サービスに移行することで、ある程度の自由が得られました。

「アプリケーション」が何かを定義するわけではないことに注意してください。モジュールはサービス/構成/イベントなどを定義します...実行中のアプリケーションは、これらすべてのものをまとめたものです。

于 2013-02-15T10:05:48.857 に答える
3

特にロギングの場合、ServiceManager. ZF2 は本質的にイベント ドリブン フレームワークであり、このイベント ドリブン アーキテクチャを可能にする機能は、私たちの利点として使用できます。ロギングはその完璧な例です。ファクトリを定義する代わりに、アプリケーションのどこからでもトリガーできるロガー イベントをアタッチするだけです。

logにイベント リスナーをアタッチしますModule.php

public function onBootstrap(MvcEvent $e)
{
    //setup some $logger

    $sharedManager = $e->getApplication()->getEventManager()->getSharedManager();

    $sharedManager->attach('*', 'log', function($e) use ($logger) {
        /** @var $e MvcEvent */
        $target   = get_class($e->getTarget());
        $message  = $e->getParam('message', 'No message provided');
        $priority = $e->getParam('priority', Logger::INFO);
        $message  = sprintf('%s: %s', $target, $message);
        $logger->log($priority, $message);
    });
}

次に、コントローラーなど、アプリケーションの任意の場所からトリガーします。

$this->getEventManager()->trigger('log', $this, array(
    'priority' => \Zend\Log\Logger::INFO, 
    'message' => 'just some info to be logged'
));
于 2013-02-15T22:54:48.617 に答える