5

Module.phpで変数または共有オブジェクト(DBアダプターなど)を作成して、すべてのビューコントローラーで使用することは可能ですか?(Zend Framework 2)

例えば:

class Module 
{
    public function onBootstrap(MvcEvent $e)
    {

        $moduleConfig = $e->getServiceManager()->get('Config')
    }
}

そしてコントローラーでは、どういうわけか以下を使用してアクセスします。

$this->moduleConfig['db']

上記では、それがdbアダプターの構成配列にすぎないことを知っていますが、それでもどのように機能しますか?

コントローラアクションでこれを実行できることがわかります。

$config = $this->getServiceLocator()->get('Config')
$dba = new DbAdapter($config['db']);

設定が必要なすべての場所でそれを実行したくありません。どうすれば次のようにできますか:$ this-> config ?? したがって、すべてのアクションで利用できます。さらに良いことに、モジュール全体でそれを行う方法は?私はこれについてすべて間違っていることを知っていますが、ZF1では、このような単純なもののためにZend_Registry :: get()がありました。私はそこにあるドキュメントやあらゆる種類のタットを読んでいますが、常にいくつかの仮定がなされており、私はただ迷子になっています。だから私が本当に欲しいのは:A)グローバルにアクセス可能な構成アイテムB)グローバルにアクセス可能なdbアダプター

コントローラで$this->dbまたは$this->config->itemを呼び出したいだけです。これは可能ですか?私は完全に単純なものが欠けていることを知っています。

また、$ this-> getServiceLocator()-> get('Config');を使用して、__constructで$this->configを設定してみました。しかし、構築中はサービスロケーターがまだ利用できないことを理解しています。モジュールのonBootstrapでpreDispatchを設定して同様のことを試みましたが、それらのアイテムをコントローラーに取り込むことができないようです。

参考までに、私はこれを私のglobal.phpに持っています(そして、いいえ、そこにとどまらない、単なる例です):

'db' => array(
        'driver' => 'Pdo',
        'dsn'   => 'mysql:dbname=mydb;host=localhost;',
        'username' => 'root',
        'password' => '',
        'driver_options' => array(
            PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
        ),

    ),

getServiceLocator()を使用して、どのアクションでもそのアイテムや他のアイテムにアクセスできます。$ this-> config-> itemのように、これらのアイテムをコントローラーのプロパティとして使用できるようにしたいと思います。

どんな指導にも感謝します!ありがとう!

4

1 に答える 1

18

わかりました...マルチパート回答。

1.サイト全体で構成変数を追加します。(およびコントローラーでアクセスする方法)

私がそれが機能するのを見たら、これは簡単でした。ただし、以下のpreDispatchによって異なります。アプリのルートで、config/autoloadにファイルをドロップします。それを呼び出す:things.config.local.php

このファイルでは、構成アイテムを含む配列を返すだけです。

<?php
return array(
    'things' => array(
        'avalue' => 'avalue1',
        'boolvalue' => true,
        ),

);

だから私は私のコントローラーでそれにアクセスしたいです。コントローラでconfigプロパティを作成すると、この方法でアクセスできます。(このプロパティを機能させるには、以下のpreDispatchでそのプロパティを設定します)私のシステムでは、次のようにその値を取得したいと思います。

$this->config['things']['boolvalue'];

ただし、次のようなアクションでそれを呼び出すことができます。

$config = $this->getServiceLocator()->get('Config');
echo $config['things']['boolvalue'];

実は簡単でした。iniファイルを使用してこれを行う方法はわかりませんが、私の場合は必要ありません。私のiniファイルは、配列に直接移動するのに大したことではありません。問題1は私のために解決しました!

2.コントローラーでpreDispatchを取得する方法(__constructは構成をロードしないため)

私の他の問題は、グローバルレベルでいくつかのオブジェクトや値にアクセスでき、コントローラーとアクションが初期化されたときにそれらをロードできることでした。私が理解しているように、コントローラーの__constructのサービスマネージャー構成にアクセスすることはできません。

$this->getServiceLocator()->get('Config');

上記は機能しません。コントローラクラスの構築中はServiceManagerがまだ利用できないためだと思います。理にかなっています。

ただし、いくつかの追加手順を実行すると、ZF1と同様にpreDispatchを機能させることができます。 その後、構成のものが機能します。また、データベースなどのグローバルオブジェクトへのアクセスも可能です。

コントローラに以下のメソッドを追加します。

protected function attachDefaultListeners()
{
    parent::attachDefaultListeners();
    $events = $this->getEventManager();
    $this->events->attach('dispatch', array($this, 'preDispatch'), 100);
    $this->events->attach('dispatch', array($this, 'postDispatch'), -100);
}

次に、preメソッドとpostメソッドを追加します。

public function preDispatch (MvcEvent $e)
{
    // this is a db convenience class I setup in global.php
    // under the service_manager factories (will show below)
    $this->db = $this->getServiceLocator()->get('FBDb');
    // this is just standard config loaded from ServiceManager
    // set your property in your class for $config  (protected $config;)
    // then have access in entire controller
    $this->config = $this->getServiceLocator()->get('Config');
    // this comes from the things.config.local.php file
    echo "things boolvalue: " . $this->config['things']['boolvalue'];
}

public function postDispatch (MvcEvent $e)
{
    // Called after actions
}

問題2は解決しました!コントローラの初期化。

3.上記をServiceManagerで使用して、Controllerで使用するDBオブジェクトをロードする方法

さて、私が最後に欲しかったのは、自分のデータベースにグローバルにアクセスすることでした。そして、コントローラー全体で$ this->db->fetchAllをどこからでも呼び出せるようにしたかったのです。

global.phpの最初のセットアップサービスマネージャー。
また、global.phpファイルのようにそのままにしておくことはしません。しかし、今のところは機能します。これらの配列をglobal.phpの戻り配列に追加します。

'db' => array(
    'driver' => 'Pdo',
    'dsn'   => 'mysql:dbname=mydb;host=localhost;',
    'username' => 'root',
    'password' => '',
    'driver_options' => array(
        PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
    ),

),
'service_manager' => array(
    'factories' => array(
        'Zend\Db\Adapter\Adapter'
                => 'Zend\Db\Adapter\AdapterServiceFactory',
        'db-adapter' => function($sm) {
                $config = $sm->get('config');
                $config = $config['db'];
                $dbAdapter = new Zend\Db\Adapter\Adapter($config);
                return $dbAdapter;
             },
        'FBDb'  => function($sm) {
                $dba= $sm->get('db-adapter');
                $db = new FBDb\Db($dba);
                return $db;
             },

    ),
),

上記では、db configをセットアップします。次に、service_managerにいくつかのファクトリがあり、アプリの残りの部分で必要なときに使用できるようになります。私の場合、古いZF1コードの一部との下位互換性のためにいくつかの便利さが必要だったので、FBDbと呼ばれるカスタムモジュールを追加しました。FabrizioBallianoによるZFBridgeと呼ばれる素晴らしいラッパー/bridge-to-zf1-style-dbクラスを見つけました。私のニーズにぴったりでした。ここで見つけることができます: https ://github.com/fballiano/zfbridge

私はそれを取り、それを少し修正して、モジュールを作りました。したがって、FBDbオブジェクトは、データベース接続としてコントローラーで使用できます。他の場所で利用したい場合は「db-adapter」と同じです。

とにかく、私のコントローラーでは、「保護された$db」を設定します。クラスの開始時に、そのプロパティを利用できるようにします。次に、上記の#2に示すように、preDispatchでFBDbデータベースオブジェクトを$this->dbに割り当てます。

$this->db = $this->getServiceLocator()->get('FBDb');

次に、アクションメソッドで、必要に応じて、次のコマンドでレコードセットまたはdb値を呼び出すことができます。

$sql = 'select * from customer where cust_nbr between ? and ?';
$rs = $this->db->fetchResults($sql, array('120400', '125250'));

または、返された配列の場合:

$rs = $this->db->fetchAll($sql, array('120400', '125250'));

(私はfetchResultsをZFBridgeに追加して、後でforeachで使用するためにdbクエリからPDO \ Resultsオブジェクトのみを返すようにしました。)

これのいくつかはおそらく悪いデザインまたは「悪いOOP」であることを私は知っていますが、それは私にとってはうまくいき、私はそれが好きです。私は個人的に、純粋なオブジェクトベースのデータエンティティをすべてに使用するのではなく、いくつかのことだけを使用します。多くの場合、私は結果セットをドロップしてそれで済ませたいだけです。:)

問題は解決しました。今のところ。ZF1に慣れている場合は、ZF2がはるかに使いやすくなります。

于 2013-01-03T19:34:06.483 に答える