【CodeIgniter】CodeIgniterでcomposer_autoloadを使ってみる 【composer】

CodeIgniterでcomposer_autoloadを使ってみる。

こんばんは、マークアップエンジニアの です。

CodeIgniter Advent Calendar 2015 - Qiita 23日目の記事です。

この記事はCodeIgniter 3.1.0-devにて検証しています。


CodeIgniter3.0はcomposerに対応しています。

CodeIgniter Advent Calendar 2015でもcomposerについて触れられています。

Advent Calendar 1日目
qiita.com


Advent Calendar 2日目
qiita.com


そのCodeIgniterでcomposerを使ってみたお話です。


composerって何?

・依存管理ツール
・nodeでいうnpmみたいなやつ

kohkimakimoto.github.io



composer使ってCodeIgniterでRedisる。

CodeIgniterでRedisにアクセスしたい。

簡単にCodeIgniterでRedisにアクセスしたいんだよなって時

phpredis
phpredis/phpredis · GitHub

を入れるのは作業としてちょっと重いんだよなーって時

composerを使えば簡単に解決します。

predis
nrk/predis · GitHub


がオススメです。
makeしなくてもphpでredisが使えちゃいます。



composerでpredisのダウンロード

CLIからapplicationディレクトリ直下に移動し下のコマンドでpredisをダウンロードします。

$  composer require predis/predis

すると「vender」というdirectoryと「composer.json」というfileができています。


application
├── composer.json
└── vender


これでcomposerを使って、「predis」をダウンロードしました。

gitやmercurial等でバージョン管理されているプロジェクトの場合、
「vender」ディレクトリの中身は含ませず「composer.json」のみバージョン管理対象してしまえば
各々の環境でcloneしてきて
CLIよりapplicationディレクトリで

$  composer install


と叩けば、predisがダウンロードされるので便利です。


predis使う。


composerでダウンロードしたものは

Hoge.php

<?php
require(APPPATH . 'vender/autoload.php');
class Hoge extends CI_Controller
{
    function index()
    {
         $predis = new Predis\Client();
    }
}


とautoload.phpを読み込めば使えますが、
上記の使い方ではなく、CodeIgniter3ではおあえつら向きの機能があります。
それが、「composer_autoloader」です。

application/config/config.phpの139行目付近にその設定がありますので記述します。

<?php
/*
|--------------------------------------------------------------------------
| Composer auto-loading
|--------------------------------------------------------------------------
|
| Enabling this setting will tell CodeIgniter to look for a Composer
| package auto-loader script in application/vendor/autoload.php.
|
|	$config['composer_autoload'] = TRUE;
|
| Or if you have your vendor/ directory located somewhere else, you
| can opt to set a specific path as well:
|
|	$config['composer_autoload'] = '/path/to/vendor/autoload.php';
|
| For more information about Composer, please visit http://getcomposer.org/
|
| Note: This will NOT disable or override the CodeIgniter-specific
|	autoloading (application/config/autoload.php)
*/
//$config['composer_autoload'] = FALSE;
$config['composer_autoload'] = TRUE;


コメントでも書かれていますがbooleanではなくstringでパスを書いても大丈夫ですが、今回はbooleanで。

$config['composer_autoload']の値をTRUEにすると「require」を書かなくても
「application/vender/autoload.php
を読み込んでくれます。



これで、下記の様にわざわざ core/CI_Controller.phpを拡張してしまえば
requireを書く必要は無く、ある程度、汎用的に使えます。


core/MY_Controller.php

<?php
class Hoge extends CI_Controller{
      public $predis;

      function __construct()
      {
          parent::__construct();
          $this->predis = new Predis\Client([
                'scheme' => 'tcp',
                'host'   => 'localhost',
                'port'   => 6379,
          ]);
      }
}


Hoge_model.php

<?php
class Hoge_model extends CI_Model
{
     public function get_hoge($i = 0)
     {
        return $res = $this->predis->get('hoge:' . $i);
     }
}

もっと使いやすく

バージョン管理しているとhostとかcloneした環境によってMY_Controller書き換えるの?
と思ったので、サンプルLibrary

libraries/Cpredis.php

<?php
class Cpredis{
	private $predis;

	function __construct($conf = array())
	{
		if ( empty($conf) || ! is_array($conf) ) $conf = [];
		$this->load($conf);
	}

	/**
	 * Load Predis\Client Instance
	 * @param array conf
	 * @param bool is_new
	 **/
	public function load(array $conf, $is_new = FALSE)
	{
		$param = $option = [];
		if ( isset($conf['param']) )  $param  = $conf['param'];
		if ( isset($conf['option']) ) $option = $conf['option'];
		if ( empty($param) && empty($option) ) $param = $conf;
		$instance = new Predis\Client($param, $option);

		if ( $is_new ) return $instance;
		$this->predis = $instance;
	}

	/**
	 * Magic Method Call Predis\Client Instance
	 **/
	public function __call($method, $args)
	{
		if ( method_exists($this->predis, $method) ) return call_user_func_array([$this->predis, $method], $args);
		return $this->predis->executeCommand(
			$this->predis->createCommand($method, $args)
		);
	}
}

と、今回はpredis管理用のLibraryっぽいものを書いてみました。
これなら、Predisインスタンス化したら使い回しできるのでらくちんですね。


configでlibraryと同名のファイルを作ると
Loaderの挙動で、自動で読み込んでくれるので
application/config/に「cpredis.php」を配置

config/cpredis.php

<?php
/**
  * NOTE:このLibraryはpredis使ってます。
  * predis => https://github.com/nrk/predis
  **/
$config['param'] = [                                                                                                                                                                                                                                                       
    'scheme'   => 'tcp',
    'host'        => 'localhost',
    'port'     => 6379,
    'password' => 'root'
];

みたいに記述してthis->load->libaray

<?php
class Hoge extends CI_Controller
{
    public function __construct()
    {
        parent::__construct();
        $this->load->library('cpredis');
    }
    
    public function index()
    {
       echo $this->cpredis->get('key:foo');
    }
}

こんな感じで書けちゃいます。



まとめ

ちょっと、predisの話なのかcomposer_autoloadの話なのかごっちゃになって申し訳ないですが
CodeIgniterでcomposerを使ってたお話です。


この記事ではpredisを使う例なのでLibraryっぽいもの書くと便利とか、あまり旨味を感じないかもしれませんが
composerは依存管理ツールですので、別にpredisだけでなく何かCodeIgniterにこの機能欲しいなーって時とかに、パッケージを調べてみると便利です。
あと、namespaceとかも指定できたり、FatControllerの防止等もできますのでcomposer_autoloadを是非ご活用ください。

参考 :
CodeIgniter初心者の方に知って欲しいCodeIgniterでのMVCについて — A Day in Serenity (Reloaded) — PHP, FuelPHP, Linux or something

Packagist


それでは、また明日。