CakePHPのModelをコマンドラインで動かしてみるテスト

CakePHPは便利そうなのだけれども、model部分で提供されるメソッドの挙動がイマイチわからない。自分としてはコマンドライン上で、これらのメソッドをガリガリと動かして調べてみたいのだけれども、そんな仕組みはなさそうなのでmodel部分を単体で動かせるようにしてみた。

準備

CakePHPの展開

最初に、CakePHPのサイトから、1.2.0.6311-betaを取ってきて適当な場所に展開して、出来たディレクトリをリネームします。

$ tar xvfz cake_1.2.0.6311-beta.tar.gz
$ mv cake_1.2.0.6311-beta piece_of_cake
      

DBの作成

次に、データベースの作成を行ないます。今回は、CakePHP レファレンスガイド中のhasManyの定義と問い合わせ使われているテーブルを作成する事にします。

ちなみにDBは、PostgreSQLを使っています。

$ createdb cakephp
$ psql cakephp < cakephp.sql
      

cakephp.sqlの内容は下記のようになっています。

cakephp.sqlの内容
CREATE TABLE users (
    id         serial  NOT NULL PRIMARY KEY,
    first_name character varying(200) NOT NULL,
    last_name  character varying(200) NOT NULL,
    username   character varying(200) NOT NULL,
    "password" character varying(100) NOT NULL,
    created    timestamp DEFAULT NULL,
    modified   timestamp DEFAULT NULL
);
INSERT INTO users VALUES (1,'ジョン','アンダーソン','psychic','c4k3roxx','now','now');
SELECT pg_catalog.setval('users_id_seq', 1, true);
	  
CREATE TABLE profiles (
    id           serial  NOT NULL PRIMARY KEY,
    name         character varying(200) NOT NULL,
    header_color character varying(200) NOT NULL,
    user_id      integer   DEFAULT 0 NOT NULL,
    created      timestamp DEFAULT NULL,
    modified     timestamp DEFAULT NULL
);
INSERT INTO profiles VALUES (1,'Cool Blue', 'アクアマリン', 1);
SELECT pg_catalog.setval('profiles_id_seq', 1, true);

CREATE TABLE comments (
    id        serial    NOT NULL PRIMARY KEY,
    user_id   integer   NOT NULL,
    body      text      NOT NULL,
    created   timestamp DEFAULT NULL,
    modified  timestamp DEFAULT NULL
);
INSERT INTO comments VALUES (1, 1, 'コメント1');
INSERT INTO comments VALUES (2, 1, 'コメント2');
INSERT INTO comments VALUES (3, 1, 'コメント3');
INSERT INTO comments VALUES (4, 1, 'コメント4');
INSERT INTO comments VALUES (5, 1, 'コメント5');
SELECT pg_catalog.setval('profiles_id_seq', 5, true);
	

bakeで設定

データーベースの作成が終わったらConsoleコマンドを使ってmodel等の設定を行ないます。

最初に bakeを使ってappディレクトリの作成を行ないます。

$ cd piece_of_cake
$ rm -r app
$ cake/console/cake bake -app ./app
Hello foo,

Welcome to CakePHP v1.2.0.6311 beta Console
---------------------------------------------------------------
App : piece_of_cake
Path: /Library/WebServer/Documents/Projects/piece_of_cake
---------------------------------------------------------------
Bake Project
Skel Directory: /Library/WebServer/Documents/Projects/piece_of_cake/cake/console/libs/templates/skel
Will be copied to: /Library/WebServer/Documents/Projects/piece_of_cake/app
---------------------------------------------------------------
Look okay? (y/n/q) 
[y] > y
Do you want verbose output? (y/n) 
[n] > n
---------------------------------------------------------------
Created: app in /Library/WebServer/Documents/Projects/piece_of_cake/app
---------------------------------------------------------------

Creating file /Library/WebServer/Documents/Projects/piece_of_cake/app/views/pages/home.ctp
Wrote /Library/WebServer/Documents/Projects/piece_of_cake/app/views/pages/home.ctp
Welcome page created
Random hash key created for 'Security.salt'
$	
      

次にデーターベースの設定をします。

$ cake/console/cake bake -app ./app
Hello foo,

Welcome to CakePHP v1.2.0.6311 beta Console
---------------------------------------------------------------
App : app
Path: /Library/WebServer/Documents/Projects/piece_of_cake/app
---------------------------------------------------------------
Your database configuration was not found. Take a moment to create one.
Database Configuration:
Name:  
[default] > 
Driver: (db2/firebird/mssql/mysql/mysqli/odbc/oracle/postgres/sqlite/sybase) 
[mysql] > postgres
Persistent Connection? (y/n) 
[n] > 
Database Host:  
[localhost] > 
Port?  
[n] > 
User:  
[root] > foo
Password:  
> 
The password you supplied was empty. Use an empty password? (y/n) 
[n] > y
Database Name:  
[cake] > cakephp
Table Prefix?  
[n] > 
Table encoding?  
[n] > EUC-JP
Table schema?  
[n] > public

---------------------------------------------------------------
The following database configuration will be created:
---------------------------------------------------------------
Name:         default
Driver:       postgres
Persistent:   false
Host:         localhost
Port:         
User:         foo
Pass:         
Database:     cakephp
Table prefix: 
Schema:       public
Encoding:     EUC-JP
---------------------------------------------------------------
Look okay? (y/n) 
[y] > y
Do you wish to add another database configuration?  
[n] > n

Creating file /Library/WebServer/Documents/Projects/piece_of_cake/app/config/database.php
Wrote /Library/WebServer/Documents/Projects/piece_of_cake/app/config/database.php
$
      

そして、modelの設定を行ないます

$ cake/console/cake bake -app ./app
Hello foo,
	
Welcome to CakePHP v1.2.0.6311 beta Console
---------------------------------------------------------------
App : app
Path: /Library/WebServer/Documents/Projects/piece_of_cake/app
---------------------------------------------------------------
Interactive Bake Shell
---------------------------------------------------------------
[D]atabase Configuration
[M]odel
[V]iew
[C]ontroller
[P]roject
[Q]uit
What would you like to Bake? (D/M/V/C/P/Q) 
> m
---------------------------------------------------------------
Bake Model
Path: /Library/WebServer/Documents/Projects/piece_of_cake/app/models/
---------------------------------------------------------------
Possible Models based on your current database:
1. User
2. Profile
3. Comment
Enter a number from the list above, or type in the name of another model.  
>
長いので省略...
      

できあがった、モデルのソースはこんな感じ

  1. user.php
  2. profile.php
  3. comment.php

初期設定ファイルの作成

CakePHPではリクエストがあると、app/index.phpが呼ばれます。ここでは、必要なインクルードファイルの読込やリクエストに応じたディスパッチ処理が行なわれます。

model単体で動かす場合は、ディスパッチ処理等は不要ですし、不要なインクルードファイルもあるので、試行錯誤しながら初期設定ファイルをつくりました。

$ cd piece_of_cake
$ ls
PieceOfCake.php         cake/                   index.php
app/                    docs/                   vendors/
      

作った初期設定ファイルを、展開して出来たディレクトリの下にPieceOfCake.phpとして置きます。

PieceOfCake.phpのソース
<?
if (!defined('PHP5')) {
	define ('PHP5', (phpversion() >= 5));
}
/**
 *  Get Cake's root directory
 */
	define('APP_DIR', 'app');
	define('DS', DIRECTORY_SEPARATOR);
	define('ROOT', dirname(__FILE__));
	define('WEBROOT_DIR', 'webroot');
	define('WWW_ROOT', ROOT . DS . APP_DIR . DS . WEBROOT_DIR . DS);

        define('DISABLE_DEFAULT_ERROR_HANDLING',true);
/**
 * This only needs to be changed if the cake installed libs are located
 * outside of the distributed directory structure.
 */
	if (!defined('CAKE_CORE_INCLUDE_PATH')) {
		//define ('CAKE_CORE_INCLUDE_PATH', FULL PATH TO DIRECTORY WHERE CAKE CORE IS INSTALLED DO NOT ADD A TRAILING DIRECTORY SEPARATOR';
		define('CAKE_CORE_INCLUDE_PATH', ROOT);
	}
	if (function_exists('ini_set')) {
		ini_set('include_path', ini_get('include_path') . PATH_SEPARATOR . CAKE_CORE_INCLUDE_PATH . PATH_SEPARATOR . ROOT . DS . APP_DIR . DS);
		define('APP_PATH', null);
		define('CORE_PATH', null);
	} else {
		define('APP_PATH', ROOT . DS . APP_DIR . DS);
		define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
	}

        require CORE_PATH . 'cake' . DS . 'basics.php';
	$TIME_START = getMicrotime();
	require CORE_PATH . 'cake' . DS . 'config' . DS . 'paths.php';
	require LIBS . 'object.php';
	require LIBS . 'inflector.php';
	require LIBS . 'configure.php';

	$bootstrap = true;
	$url = null;

//	require LIBS . 'file.php';
	require LIBS . 'cache.php';
	Configure::getInstance();
//require LIBS . 'session.php';
//require LIBS . 'security.php';
	require LIBS . 'string.php';
        require LIBS . DS . 'model' . DS . 'model.php';
        require  'app_model.php';
        Configure::write('debug', 2);
?>	

動かしてみる

Userデータを取り出してみる

ちゃんと動作するか、先ほど作成したPieceOfCake.phpをインクルードし、Userデータを取り出すUser.phpを作って確かめてみます。

User.phpのソース
<?php
ini_set('include_path', ini_get('include_path') . ':/Library/WebServer/Documents/Projects/piece_of_cake' );
include_once('PieceOfCake.php');
include_once('models/user.php');

function main(){
    $User = new User();

    if( $data=$User->findAll() ){
	echo "++++++++++++++++ findAll()の返り値 +++++++++++++++\n";
	print_r($data);
    }
}
main();
?>

結果は下記のようになりました。ちゃんと動きます!

$ php User.php
++++++++++++++++ findAll()の返り値 +++++++++++++++
Array
(
    [0] => Array
        (
            [User] => Array
                (
                    [id] => 1
                    [first_name] => ジョン
                    [last_name] => アンダーソン
                    [username] => psychic
                    [password] => c4k3roxx
                    [created] => 2008-04-09 18:11:14.772833
                    [modified] => 2008-04-09 18:11:14.772833
                )

            [Profile] => Array
                (
                    [id] => 1
                    [name] => Cool Blue
                    [header_color] => アクアマリン
                    [user_id] => 1
                    [created] => 
                    [modified] => 
                )

            [Comment] => Array
                (
                    [0] => Array
                        (
                            [id] => 1
                            [user_id] => 1
                            [body] => コメント1
                            [created] => 
                            [modified] => 
                        )

                    [1] => Array
                        (
                            [id] => 2
                            [user_id] => 1
                            [body] => コメント2
                            [created] => 
                            [modified] => 
                        )

                    [2] => Array
                        (
                            [id] => 3
                            [user_id] => 1
                            [body] => コメント3
                            [created] => 
                            [modified] => 
                        )

                    [3] => Array
                        (
                            [id] => 4
                            [user_id] => 1
                            [body] => コメント4
                            [created] => 
                            [modified] => 
                        )

                    [4] => Array
                        (
                            [id] => 5
                            [user_id] => 1
                            [body] => コメント5
                            [created] => 
                            [modified] => 
                        )

                )

        )

)
      

Userデータを取り出してみる

次にProfileデータを取り出すProfile.phpを作って確かめてみます。

Profile.phpのソース
<?php
ini_set('include_path', ini_get('include_path') . ':/Library/WebServer/Documents/Projects/piece_of_cake' );
include_once('PieceOfCake.php');
include_once('models/profile.php');

function main(){
    $Profile = new Profile();

    if( $data=$Profile->findAll() ){
	echo "++++++++++++++++ findAll()の返り値 +++++++++++++++\n";
	print_r($data);
    }
}
main();
?>	

こちらも、問題なく動作しているようです。

$ php Profile.php
++++++++++++++++ findAll()の返り値 +++++++++++++++
Array
(
    [0] => Array
        (
            [Profile] => Array
                (
                    [id] => 1
                    [name] => Cool Blue
                    [header_color] => アクアマリン
                    [user_id] => 1
                    [created] => 
                    [modified] => 
                )

            [User] => Array
                (
                    [id] => 1
                    [first_name] => ジョン
                    [last_name] => アンダーソン
                    [username] => psychic
                    [password] => c4k3roxx
                    [created] => 2008-04-09 18:11:14.772833
                    [modified] => 2008-04-09 18:11:14.772833
                )

        )

)      

初期設定ファイルへのパスが通っていれば、どこのディレクトリからでも実行する事ができます。これを使ってmodel関数を色々いじり回して見ようと思います。

Last modified: Fri May 09 18:59:21 2008 JST