[Zend Framework2]共通モジュールの追加方法

前回は、Socket.IO を用いたチャットアプリについて御紹介しました。
今回は、PHPのフレームワークであるZend Framework2に共通モジュールを追加する方法をご紹介します。

Zend Framework2(以下、zf2)では、作成するアプリケーションの各機能をモジュールという単位でを管理します。
開発規模が大きくなると、用途ごとにモジュールの追加を行うことになると思いますが、共通で利用する機能やクラス(以下、共通モジュール)は、各モジュールとは別のディレクトリを用意して管理するのが一般的です。

■ディレクトリ構成例

applicaton
 ├library
 │ └Common          //共通モジュール
 │  └Sample.php
 │
 ├vendor
 │ ├Zend
 │ └ZendXml
 │
 └ZendSkeletonApplication
   └module
    └Application      //Applicationモジュール
     └src
      └Application
       └Controller
        └IndexController.php

共通モジュールに名前空間を使用している場合、zf2アプリケーションのデフォルト設定では、共通モジュールの名前空間を使用することができません。

<Common.php>

<?php

namespace Common;

class Sample
{
    public static function echoHello()
    {
        echo "Hello!!!"."<br>";
    }
}
?>

<IndexControlelr.php>

<?php

namespace Application\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;

//用意した共通モジュールのSampleクラス(Sample.php)のimport
use Common\Sample;

class IndexController extends AbstractActionController
{
    public function indexAction()
    {
    	Sample::echoHello();   //Common\Sampleがみつからないとエラーが発生
    }
}
?>

試しにIndexControllerのindexActionを実行してみます。
 ※xampp環境を使用しています
http://localhost/server/ZendSkeletonApplication/public/

<実行結果>

これは、定義した名前空間でのパスが解決できないことによって発生するエラーです。
zf2アプリケーションのデフォルト設定では、アクセスしたURLのルーティング設定に一致するモジュールと、zf2本体の2つまでのパス設定しか行わないため、Sampleクラスまでのパスが解決できていないのです。

zf2のインストール手順として公開されている情報の多くは、このことについてあまり触れられていませんが、前述したモジュールとzf2までの名前空間登録はそれぞれ以下の箇所で定義されています。

■各モジュールの名前空間登録
zf2アプリケーションルート(本記事ではZendSkeletonApplication)/module/Module.php

	//31行目あたり
    return array(
        'Zend\Loader\StandardAutoloader' => array(
            'namespaces' => array(
                __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
            ),
        ),
    );

zf2ではStandardAutoloaderクラスでファイルのオートロードを行います。
配列のキーとして設定している “namespaces” はStandardAutoloaderクラス内部で定数として定義されており、”namespaces”をキーにもつ値は、StandardAutoloader内の処理で名前空間として登録されます。

<StandardAutoLoader.php>

	...

	//26行目あたり
    const LOAD_NS          = 'namespaces';

    ...

    //96行目あたり
    if (is_array($pairs) || $pairs instanceof \Traversable) {
        $this->registerNamespaces($pairs);   //名前空間の登録。 $pairs -> "namespaces"の要素 "__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__"をもつ連想配列が入っている
    }

■zf2の名前空間登録
zf2アプリケーションルート(本記事ではZendSkeletonApplication)/init_autoloader.php

	//42行目あたり
    Zend\Loader\AutoloaderFactory::factory(array(
        'Zend\Loader\StandardAutoloader' => array(
            'autoregister_zf' => true,
        )
    ));

zf2の名前空間登録はautoregister_zfの要素にtrueを設定しているだけですが、行っていることはモジュールの時と同じです。
“autoregister_zf”も”namespaces”同様、StandardAutoloaderクラス内部で定数として定義されており、値にtrueが設定されている場合、自動的にzf2本体までの名前空間を登録します。

<StandardAutoLoader.php>

	...

	//29行目あたり
    const AUTOREGISTER_ZF  = 'autoregister_zf';

    ...

    //90行目あたり
    if ($pairs) {   //$pairs -> "autoregister_zf"の要素 trueが入っている
        $this->registerNamespace('Zend', dirname(__DIR__));     //Zendまでの名前空間の登録
        $this->registerNamespace('ZendXml', dirname(dirname((__DIR__))) . DIRECTORY_SEPARATOR .  'ZendXml');    //ZendXmlまでの名前空間登録
    }

“namespaces”,”autoregister_zf”共に、”Zend\Loader\StandardAutoloader”をキーとする要素に設定する連想配列のキーになっています。
この、”Zend\Loader\StandardAutoloader”をキーに持つ連想配列は、AutoloaderFactoryクラスのfactoryメソッドの引数として渡ります。
※<zf2>の名前空間登録ソースコード参照 ※2行目

factoryメソッドでは、”Zend\Loader\StandardAutoloader”のキーを見つけると、その要素をStandardAutoloaderクラスのsetOptionメソッドに渡して 名前空間の登録処理を行います。

そのため、init_autoloader.phpのfactoryメソッドに渡している連想配列に”namespaces”をキーとした配列を設定すると、好きなように名前空間の登録をすることが出来ます。
本記事で使用している、共通モジュール(Common)の名前空間登録は以下のようになります。

zf2アプリケーションルート(本記事ではZendSkeletonApplication)/init_autoloader.php

	Zend\Loader\AutoloaderFactory::factory(array(
	    'Zend\Loader\StandardAutoloader' => array(
	        'autoregister_zf' => true,

	        //共通モジュールの名前空間登録
	        'namespaces' => array(
	                "Common" => getcwd(). "./../library/Common",
	        ),
	    )
	));

これで先ほどと同じようにIndexControllerのindexActionを実行します。

<実行結果>

無事にSampleクラスのechoHelloメソッドを実行することが出来ました。

以上で、zf2における共通モジュール追加設定のご紹介は終了です。
最後までご覧いただき有難うございました。


弊社では全国各地の請負い(ご自宅)で作業協力頂ける、フリーランスエンジニアの方を常時探しております。
ご興味ある方は、お気軽にお問い合わせ下さい。


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*