Cake PHPの覚書

CakePHPを導入直後にやるべきこと

Cake2.4.x以降の場合、以下の設定を行っておく必要がある。
  1. タイムゾーンの変更
  2. ランダム用のシード値を変更

ビュー(ctp)を使わず直接コントローラから値を出力する方法。


	function index() {

		$this->autoRender = false;//ビューを使わない。
		ob_start();
		$html='hello world日本語';
		ob_end_clean();
		return $html;//ブラウザに出力するHTML

	}
	

モデルでデータベースのテーブルと関連付けないようにする。

モデルに下記のメンバを追加する。

	public $useTable = false; /* データベースのテーブルを使用しない */
	

コントローラ、ビュー、モデルをフォルダで階層化する方法。

Modelフォルダ内にUtilというフォルダで階層化する場合、Config/bootstrap.phpに下のようなコードを追加すればよい。
	App::build(array(
		'Model'=>array(
			ROOT.DS.APP_DIR.DS.'Model'.DS.'Util'.DS,
			ROOT.DS.APP_DIR.DS.'Model'.DS,
		)
	));

	

外部クラスを使う方法。

CsvIo.phpという外部クラスを利用する場合の例。
CsvIo.phpをVendorフォルダに追加。
コントローラやモデルで以下のようにして使う。
	//CsvIo.phpをインポート
	App::uses('CsvIo','Vendor');

	//後は通常のPHPと同様にクラスを使う。
	$cio=new CsvIo();
	$data=$cio->load('tmp/dummy.csv');
	

※Vendor内でもフォルダ分けして階層化することが可能。
VendorにAnimalフォルダを作成し、その中にNeko.phpクラスを追加した場合、以下のようにして宣言する。
App::uses('CsvIo','Vendor/Neko');

※2 クラス名とファイル名は同じにせねばならない。

関数ファイルを使う場合。(クラスでない関数集ファイル)

ADebug.phpという外部クラスを利用する場合の例。
Vendorフォルダ内に、ADebug.phpを追加。
コントローラやモデルで以下のようにインポートすれば利用できるようになる。
	//関数集ファイルを宣言。
	App::import('Vendor','ADebug');

	//通常のPHPのように関数を利用できる。
	a_debug('hello world');
	

※require_onceを使うこともできる。
require_once '../Vendor/ADebug.php';

POSTからデータを取得する方法

	$token=$this->request->data['token'];
	

コントローラで対応していないモデルを使う方法

たとえばTestAContollerでTestBモデルを使う場合。
	function test(){
		App::uses('TestB','Model');
		$this->TestB=new TestB();
		$this->TestB->find1();
	}
	

SQLインジェクションとXSS(クロスサイトスクリプティング)のサニタイズ

配列内の文字列をまとめてSQLインジェクション・サニタイズ
 SQL用の重要記号である「'」や「"」の前に¥(バックスラッシュ)を付ける。
	$ary=Sanitize::clean($ary, array('encode' => false));
	
サニタイズの詳細(HTMLのソースを確認)
サニタイズ前サニタイズ後
'¥'
::
//
<<
¥¥¥
¥n¥¥n
&&
||||
"¥"
;;
,,
※XSS・サニタイズは行わないので注意。
「¥」は2重になる。
配列内の文字列をまとめXSS・サニタイズ
 SQL用の重要記号である「<」や「>」などを「&lt」、「&gt」に変換する。
	$ary=Sanitize::clean($ary, array('encode' => true));
	
サニタイズの詳細(HTMLのソースを確認)
サニタイズ前サニタイズ後
'&#039;
::
//
<&lt;
¥¥¥
¥n¥¥n
&&
||||
"&quot;
;;
,,
※SQLインジェクション・サニタイズは行わないので注意。
こちらも「¥」は2重になる。
文字列に対してSQLインジェクション対策
 SQL用の重要記号である「'」や「"」の前にバックスラッシュを付ける。

	$str=Sanitize::escape($str);//例、「'」→「¥'」
	
SQLインジェクション・サニタイズの解除
 Sanitize::escape関数でサニタイズされた文字列を元に戻す関数。
 「¥'」→「'」    「¥"」→「"」
	function release_sql_sanitaize($v){
		$v= str_replace("\\'", "'", $v);
		$v= str_replace("\\\"", "\"", $v);
		return $v;
	}
	
文字列に対してXSS対策
	$str=Sanitize::html($str);
	// 「<」→「&lt」
	
※Sanitize::html()省略したh()関数が便利。
	echo h($str);// 「<」→「&lt」
	
インクルードについて
 Sanitizeクラスは標準でインクルードされているとのことだが、インクルードされていないこともあるので、その場合は以下のコードを記述する。
	App::uses('Sanitize', 'Utility');
	
半角英数字以外を除去
	$str=Sanitize::paranoid($str);
	

一部の記号は残す場合。例:「@」
	$str=Sanitize::paranoid($str, array(' ', '@'));
	

Noticeエラーを表示させない

ファイルの上部に宣言。class名よりも上に。
	error_reporting(E_ALL ^ E_NOTICE);
	

セッション(session)へのデータ保存と読取

テスト
	$this->Session->write('tora',$tora);//セッションへの書き込み
	$tora2=$this->Session->read('tora');//セッションから読取
	$this->Session->delete('tora');//セッションから削除
	$this->Session->destroy();//セッションを全てクリアし新鮮なセッションを作り直す。
	

モデル名と異なるテーブルと関連付ける

モデルにモデル名とは異なるテーブルに関連付けることができる。
ただし、リテラル名( AS ○○)はモデル名になる。例では「 test_bs AS TestJoin 」。
	class TestJoin extends Model {

		var $name='TestJoin';

		var $useTable='test_bs';//test_bsテーブルと関連付ける。
	

発行したSQLのログを画面に表示する

app/config/core.phpを開く。
以下のコードを'2'に設定する。
	Configure::write('debug', 2);


'1'にするとSQLのログが表示されない。
'2'にするとSQLのログが表示される。

以下のコードをいれると指定場所にSQLログをはくことができる
	echo $this->element('sql_dump'); 


参考元

コンフィグ(Config)のデータを取得

CakePHPでは共通データなどを設定として定義できる。以下に設定方法と使用例を示す。


コンフィグデータの設定場所と記述例
設定場所→ app/Config/datas/yagi_list.php
記述例
	Configure::write('yagiLists', array(
		1 => 'white',
		2 => 'black',
		3 => 'okinawa',
		3 => 'brown',
	));
	
app/Config/bootstrap.phpに以下のコードを追加する。
config('datas/yagi_list.php');
	


コンフィグからデータを利用する例
	$yagis=Configure::read('yagiLists');
	

複数行のPOST

一覧表の各行にテキストボックスを作成している場合など、inputタグを配列として定義したい場合がある。
このような場合、モデル名とフィールド名の間に要素番号を挟む。
「モデル名.要素番号.フィールド名」
	  echo $form->input('ModelA.0.animal_name');
	  echo $form->input('ModelA.1.animal_name');
	  echo $form->input('ModelA.2.animal_name');
	  echo $form->input('ModelA.3.animal_name');
	


ビューへの記述例(モデル名がTbl、フィールド名がtest_nameの場合)
	echo $this->Form->create('Tbl', array('url' => '#'));
	foreach ($data as $i => $ent) {
	    echo $this->Form->input($i . '.test_name', array(
	        'value' => $ent['Tbl']['test_name']
	    ));
	}
	

Cake PHPのコアライブラリを別のディレクトリに配置する場合の設定方法

コアライブラリは普通、appが配置してあるディレクトリと同じ場所にあるlibフォルダ内にあります。
libフォルダ内にあるCakeフォルダがコアライブラリです。
コアライブラリCakeは別のディレクトリに移動させることが可能です。

コアライブラリを以下の場所に移す場合で設定の手順を示します。
ローカル環境→ C:\web\pleiades\xampp\htdocs\CakeZss2014/Cake
サーバー環境→ www/CakeZss2014


手順
① webroot/index.phpを開く。
② 下記のコード(コメントアウトされている)あたりを探す。
//define('CAKE_CORE_INCLUDE_PATH', ROOT . DS . 'lib');
③ 以下のコードを記述する。
	switch($_SERVER['SERVER_NAME']) {
		case 'localhost':
			define('CAKE_CORE_INCLUDE_PATH', 'C:\web\pleiades\xampp\htdocs\CakeZss2014');

			break;
		default:
			define('CAKE_CORE_INCLUDE_PATH', '/CakeZss2014');
			break;
	}
	
以上でOK.


※単体テストを利用する場合、webroot/test.phpも同様に編集します。
	

ローカル環境およびLAN環境でのDB設定

ローカル環境とLAN環境(社内環境やオフィス内環境)の接続設定は同じ。

app/Config/database.php
	class DATABASE_CONFIG {

		public $default = array(
			'datasource' => 'Database/Mysql',
			'persistent' => false,
			'host' => 'localhost',
			'login' => 'root',
			'password' => 'xxx',
			'database' => 'tanuki_db',
			'prefix' => '',
			'encoding' => 'utf8',
		);


	}
	

LAN環境内の他のPCが見る場合、以下へアクセス。自PCからも可能。
http://192.168.xxx.xxx/
「192.168.xxx.xxx」はPHPソースが置いてあるPCに割り当てられたプライベートIPアドレス。
プライベートIPアドレスはコマンドプロンプトでipconfigとやると見れる。
MySQLはmy.iniファイルのbind-addressがコメントアウトになっていれば良い。デフォルトでは多分この設定。
# bind-address="127.0.0.1"

ページネーション

最低限の設定方法 nekosテーブルと画面を関連付けている場合、メインのモデル(Neko)を一番左側に持っていく。
$public $uses = array('Neko','SubModel');

悪例(メインのモデルが左側でない):
×$public $uses = array('SubModel','Neko');
コントロールのアクションメソッドで以下のような一覧データのset方法を変更する。 変更前
$this->set('data',$data);
変更後(ページネーション対応)
$this->set('data',$this->paginate());

以上で最低限の設定はOK。デフォルトでは20件のレコードが表示される。


ビュー側の様々な表示
「前へ」などのページネーション用のリンクを作る。
		< ?php
		echo $this->Paginator->prev('< 前へ', array(), null, array('class' => 'prev disabled'));
		echo $this->Paginator->numbers(array('separator' => ''));
		echo $this->Paginator->next('次へ >', array(), null, array('class' => 'next disabled'));
		?>
		

データ数を表示する
< ?php echo $this->Paginator->counter(array('format' => 'データ数:%count%' ));?>

現在ページと全ページ数を表示する
< ?php echo $this->Paginator->counter(array('format' => 'ページ:{:page}/{:pages}')); ?>

ソート用のリンク
HTMLテーブルのフィールド名をソートリンクにすることができる。
< ?php echo $this->Paginator->sort('title','タイトル'); ?>



詳細な設定
コントローラの$paginatorメンバに詳細な設定を入れることができる。
		public $paginator = array(
		 'Neko' => array(
			 'fields' => array('id,rec_date,title,note'),
			 'conditions' => array('フィールド[演算子] => 値),
			 'limit' =>10,
			 'order' => array('rec_date' => 'desc'),
		 ));
		
モデル名はNeko
フィールドはid,rec_date,title,note
制限数:10件
ソートはrec_dateの降順



サンプル
DBテーブル名はrecs。rec_dateフィールドに検索条件を指定、また降順でソート指定も行っている。表示件数は30件を指定。
	public function index() {



    	//ページネーションへセット
    	$this->paginate = array(
    			'Rec' => array(

    					'conditions' => "rec_date < '2014/4/1'",
    					'limit' =>30,
    					'order' => array('rec_date' => 'desc'),
    			));

    	$this->set(array(
    			'data'=> $this->paginate(),

    	));


    }
		
※「$this->find();」は必要としない。


参考元