cakePHP1.3でリクエストによって使用するcontrollerのディレクトリを変更する

Twitter ツイート Hatena Bookmark ブックマーク

一般的なWebのAPIとかだとよく「/api/v1/〜」みたいな、URLでAPIを提供しているところが多いと思います。
cakePHPでももちろんそういうことは出来ます。

この場合はrouters.phpのでURLの指定を以下のようにすれば良いと思います。
app/config/routers.php

1
Router::connect('/api/:version/:controller/:action/*',array());

ただ、apiのバージョン「/api/v1」と「/api/v2」でコントローラを全く違うものにしたいものです。
少なくとも、僕の場合はそうでしたw
うまく説明できないんですが、controllersのディレクトリで以下のように分けて使用したかったのです。

1
2
3
4
5
6
7
-----
  |
  |----controllers → 一般
           |
           |----v1 → /api/v1 (version1のAPIのコントローラ)
           |
           |----v2 → /api/v2/ (version2のAPIのコントローラ)

方法としては、bootstrapで読み込むコントローラディレクトリを指定してあげれば良いみたいです。
ただし、キャッシュの問題があるのでキャッシュのconfigの部分の変更も必要です。
ということでbootstrapとcoreを書き換えればよいっぽいです。

「Cache::config(‘default’, array(‘engine’ => ‘File’));」の部分を以下のように書き換えてください。

app/config/core.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
 * APIモードでのアクセスの場合
 */
$useApi = false;
if ( isset($_GET['url']) ) {
	$parse_url = explode('/',trim($_GET['url'], '/'));
	if ( isset( $parse_url[0], $parse_url[1]) && $parse_url[0] == "api" && preg_match('/^v([0-9])+/', $parse_url[1],$matches)) {
		$useApi = true;
		Configure::write("Api.version",$matches[0]);

		$result = Cache::config('default', array(
			'engine' => 'File',
			'prefix' => 'api_'.$matches[0],
			'path' => dirname(CACHE) . DS . 'cache_api' . DS,
		));
	}

	unset($parse_url);
}

if ( !$useApi ) {
	Configure::write("Api.version",false);
	Cache::config('default', array('engine' => 'File'));
}

でもって次はbootstrapの一番下に以下の処理を追記します。
app/config/bootstrap.php

1
2
3
4
5
6
7
8
$apiVersion= Configure::read("Api.version");
if ( $apiVersion ) {
	App::build(array(
		'controllers' => array(
			ROOT.DS.APP_DIR.DS.'controllers'.DS.'api'.DS.$matches[0].DS,
		),
	));
}

最後にtmp/cacheのディレクトリをコピーしてtmp/cache_apiを作ってください。
これで「http://hoge.com/api/v1/index/」でアクセス「http://hoge.com/api/v2/index/」でアクセスしてきたときにディレクトリを切り替えることが可能になります。
controllersディレクトリとかって以外とファイル数が多くなるので便利かもしれません。

なんかこの辺の処理の書きにくさがcakePHPがありますね。。。。
Zend Frameworkのほうが結構柔軟だなーとか思いました。(良い悪い別にしてね。

参考
http://q.hatena.ne.jp/1279743459
CakePHPのcontrollerをprefix別に分ける

comments powered by Disqus
Built with Hugo
テーマ StackJimmy によって設計されています。