CodeIgniterの学習 46 - CodeIgniter上でPEAR、Zend Frameworkの簡単ロードを実現する(改造版)

ええと、今日は先日の CodeIgniterの学習 44 - PEARをCodeIgniter上で使えるようにする http://d.hatena.ne.jp/dix3/20081118/1226994170 の続き。
(include_pathの追加、ソースの設置等の前提は既に済んでいるものとする。)


先日のエントリーでは、

どっちかというと、他のサンプルソースをまんまコピペできてミスが少なそうだから、
pearloaderを使わずに、require_onceで直接書いた方が俺は好き。

と書いた。

また、サンプルとして、

<?php
//上略
function index()
{
  //pearを使った例
  $this->load->library('pearloader');
  $http_request = $this->pearloader->load('HTTP','Request');
  $http_request->setURL('http://www.example.com/');
  $http_request->sendRequest();
  var_dump( $http_request->getResponseBody());

  //おまけ Zend_Httpを使った例
  require_once('Zend/Http/Client.php');
  $client = new Zend_Http_Client();
  $client->setConfig(array('maxredirects' => 0,'timeout'=>30));
  //GETパラメータのセット
  $client->setParameterGet(array(
      'foo'  => '1',
      'bar' => '2',
  ));
  $client->setUri('http://www.example.com/search');
  $response = $client->request();
  var_dump($response->getBody());
  //GETパラメータのリセット
  $client->resetParameters();

}
//下略
 ?>

ってしていたのだけど、

やっぱり、美意識的に

$obj = $this->pearloader->load();

とか、

$obj = $this->zendloader->load();

とかで、各種ライブラリを読み込みたくなったので、
ここではpearloaderをコピペ+改造してzendloaderを作ってみた。
(確か海外サイトでも同様なのを見かけた記憶がある)


俺の美意識が果たして正常かはこの際考えない。混ぜている時点でアレだが。


何度か書いたけど俺的にはCIは基本部分の骨格、
中のソースはいろいろ混ぜるっていう使い方をする方針。
ドキュメント豊富なライブラリはなんでも取り入れる。伝達しやすいし。
(ただ、混ぜちゃうとライセンス的に注意が必要)


改造版pearloaderと、新設zendloader

いくつか俺好みに改造した。

(改造点1)
元ネタ(http://codeigniter.com/wiki/PEAR_integration/)のpearloaderでは、

$http_request = $this->pearloader->load('HTTP','Request');

の様に、

$this->pearloader->load('パッケージ(ディレクトリ)名','拡張子無しのファイル名',任意のパラメータ配列);

として読み込んでいるのだが、(pearのHTTP/Request.phpをnewしている)

これだと、

みたいにディレクトリ名が無い場合に、読み込めない。

なので、

pear/HTTP/Request.php

$obj = $this->pearloader->load('HTTP/Request',$param_array);

Zend/Http/Client.phpは、

$client = $this->zendloader->load('Http/Client',$param_array);

みたいに、

第一引数は、
頭のpear/又はZend/を取り除きつつ末尾の拡張子を除いたパス名

第二引数は、
コンストラクタに渡す任意のパラメータ配列

として使えるように統一した。




(改造点2)

全部が全部newするようなパッケージだと良いのだが、ライブラリによってはnewせずに、静的に呼び出す類のものもある。

ついでなので、require_once() しかしない、pearloader->req();と、zendloader->req();を作った。


注意

(注意1)
ベースのパスのインクルードは、先日のエントリで、

ini_set( 'include_path', APPPATH . 'my_classes/' . PATH_SEPARATOR. APPPATH . 'my_classes/pear' );

というのを既に設定済み(事情によりドキュメントルート/index.php内に記述済み)

(注意2)
このpearloader,zendloaderを作っても、
先日のZend_Logを使った場所の様に、呼び出す場所によっては使えない場所もある。
(通常のヘルパ、コントローラ、モデル内ならば使えるけど)



改造版ソース

いつもながら無保証

PEAR用:
application/libraries/Pearloader.php

<?php if ( !defined( 'BASEPATH' ) ) exit( 'No direct script access allowed' );
class Pearloader {
  function load( $package,$options = null )
  {
    require_once( $package . EXT );
    $classname = str_replace( '/', '_', $package ) ;
    if ( is_null( $options ) ) {
      return new $classname();
    }else {
      return new $classname( $options );
    }
  }
  function req( $package )
  {
    require_once( $package . EXT );
  }


} //endofclass
/**
 * End of file Pearloader.php
 */
/**
 * Location: ./application/libraries/Pearloader.php
 */
 ?>


Zend Framework用:
application/libraries/Zendloader.php

<?php if ( !defined( 'BASEPATH' ) ) exit( 'No direct script access allowed' );
class Zendloader {
  function load( $package, $options = null )
  {
    $fname = 'Zend/' . $package . EXT;
    require_once( $fname );

    $classname = str_replace( '/', '_', 'Zend/' . $package ) ;
    if ( is_null( $options ) ) {
      return new $classname();
    }else {
      return new $classname( $options );
    }
  }
  function req( $package )
  {
    $fname = 'Zend/' . $package . EXT;
    require_once( $fname );
  }

} //endofclass
/**
 * End of file Zendloader.php
 */
/**
 * Location: ./application/libraries/Zendloader.php
 */
 ?>

頭のZend/は不要(勝手に補完する)



動作確認

適当なコントローラ等で、

<?php
//上略
function index(){
  //pearを使った例
  $this->load->library('pearloader');
  $http_request = $this->pearloader->load('HTTP/Request');
  $http_request->setURL('http://www.example.com/');
  $http_request->sendRequest();
  var_dump( $http_request->getResponseBody());

  //おまけ Zend_Httpを使った例
  $this->load->library('zendloader');
  $client = $this->zendloader->load('Http/Client');
  $client->setConfig(array('maxredirects' => 0,'timeout'=>30));
  //GETパラメータのセット
  $client->setParameterGet(array(
      'foo'  => '1',
      'bar' => '2',
  ));
  $client->setUri('http://www.example.com/search');
  $response = $client->request();
  var_dump($response->getBody());
  //GETパラメータのリセット
  $client->resetParameters();
}
//下略
 ?>

としてみる。

結果は一昨日と同じ。



これですっきりした。