超簡単なインスタンスコンテナ 動的編

[PHP] : 超簡単なインスタンスコンテナ 動的編

概要

以前のエントリで超簡単なインスタンスコンテナというタイトルで記事を書きましたが、
コンテナに格納できるインスタンスが静的に呼び出されるものだったので、
動的に呼び出されるように修正してみました。以前のエントリは以下のものです。
http://d.hatena.ne.jp/yutakikuchi/20100907/1283877423

改良したインスタンスコンテナ



class Container {

static private $instance_ = array();

private function __construct() {}

static public function get( $class, $path = null ) {
 
    if( isset( self::$instance_[ $path ] ) ) {
        return self::$instance_[ $path ]; 
    }

    if( !is_readable( $path ) ) {
        throw new Exception();
    }

    require_once $path;
    $instance = new $class;
    self::add( $path, $instance );
    return $instance;

}

static public function add( $path, $instance ) {
    if( !isset( self::$instance_[ $path ] ) ) {
        self::$instance_[ $path ] = $instance;
    }
}

}

Containerに格納したいクラス名、ファイルパスを指定してgetメソッドを呼び出すと
Containerが唯一のインスタンスを保持してくれます。

コンテナに格納するクラス

sample.php



class Sample {

private $count_ = 0;

public function __construct() {
    $this->count_++;
    
}

public function call() {
    echo "sample method \n";
}

public function getCount() {
    return $this->count_;
}

}

test.php



class Test {

public function call() {
    echo "test method \n";
}

}

clientコード

実際に一回の実行で複数回コンテナからgetにてインスタンスを取得したときに
何回コンストラクタが呼び出されているのかを見てみます。

client.php


require_once './Container.php';
require_once './client2.php';


$test = Container::get( 'test', './test.php' );
$test->call();

$sample = Container::get( 'sample', './sample.php' );
$sample->call();

client2::execute();

client2.php


require_once "./Container.php";
class client2 {

static public function execute() {
    $sample = Container::get( 'sample', './sample.php' );
    echo $sample->getCount() . "\n";
}

}

実行結果

上のclient.phpを実行してみます。以下は実行結果です。

test method 
sample method 
1

最後の数字がsample.classのコンストラクタ呼び出し回数です。
1回のみ呼び出されています。2回目のgetではコンテナに格納されている
インスタンスが返されていることが分かります。