CakePHP
CakePHP = MVC + CoC
※対象:CakePHP 1.3.x
★命名規則
ファイル
Controller 名前_controller.php
View 名前のフォルダ / アクション.ctp
Model テーブル.php
クラス
Controller 名前Controller
Model テーブル
http://サーバー/ディレクトリ/コントローラー/アクション
※アクションを省略すると、indexを呼ぶ
例:
http://localhost/cakephp/sample/
http://localhost/cakephp/sample/add
http://localhost/cakephp/sample/edit?id=番号
★ディレクトリ
cakephp
app
controllers
components
sample_log.php
sample_controller.php
views
sample
index.ctp
result.ctp
layouts
sample.ctp
elements
sample.ctp
helpers
sample.php
webroot
css
cake.sample.css
models
sample.php
★サンプルコード(モデルを利用しない例)
コントロール(ビューを利用しない)
class SampleController extends AppController {
public $name = "Sample";
public $uses = null; //使用するモデル デフォルト:samplesテーブル
public $autoRender = false; //views(*.ctp)を読み込む デフォルト:true
※ファイルをダウンロードする際に設定
function index(){
echo "<html>";
...
echo "</html>";
}
}
コントロール(ビューを利用する)
class SampleController extends AppController {
public $name = "Sample";
public $uses = null;
public $autoRender = true;
public $autoLayout = true; //レイアウトを指定 デフォルト:true
public $layout = "sample"; //独自のレイアウトを指定
public $components = array('SampleLog');
public $helpers = array('Sample');
function index(){
// レイアウト設定用
$this->set("page_title", "xxx");
$this->set("content_header", "xxx");
$this->set("content_footer", "xxx");
//フォームの内容
if ($this->data){
$input = $this->data["input"];
...
}
$rtn = $this->SampleLog->component_method();
}
function result(){
App::import("sanitize"); //ライブラリのロード
$input = $this->params['form']['input']; //POSTの場合
//$input = $this->params['url']['input']; //GETの場合
$result = Sanitize::stripAll($input); //スクリプトなどを無効にする
$this->set("result", $result);
}
}
レイアウト
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title><?php echo $page_title; ?></title>
<?php echo $html->css("cake.sample"); ?>
</head>
<body>
<div id="header"><?php echo $content_header; ?></div>
<div id="content">
<?php echo $content_for_layout; ?><br /><br />
</div>
<div id="footer"><?php echo $content_footer; ?></div>
</body>
</html>
ビュー index.ctp
<?php echo $this->element('sample'); ?>
Formヘルパーの利用例
<?php
echo $form->create(null, array('type'=>'post', 'action'=>'.'));
echo $form->input("input");
echo $form->end("送信");
?>
HTMLの利用例
<form method="post" action="./result">
<input type="text" name="input" />
<input type="submit" value="送信" />
</form>
<?php echo $sample->helper_method(); ?>
※Formヘルパー
$form->password( 名前 , 属性 ); パスワード
$form->hidden( 名前 , 属性 ); 非表示
$form->textarea( 名前 , 属性 ); テキストエリア
$form->checkbox( 名前 , 属性 ); チェックボックス
$form->label( 名前 , 属性 ); ラベル
$form->radio( 名前 , 配列 , 属性 ); ラジオボタン
$form->select( 名前 , 配列 , 属性 ); 選択リスト
ビュー result.ctp
<b><?php echo $result; ?></b>
<a href="./">戻る</a>
コンポーネント
class SampleLogComponent extends Object{
function component_method(){
...
}
...
}
ヘルパー
class SampleHelper extends AppHelper {
function helper_method(){
...
}
...
}
★サンプルコード
/**
* 圧縮ファイル作成コンポーネント
*
* 使用例:
* <code>
* $this->FileArchive->compress('sample.zip', '/target_dir/');
* </code>
* @package components
*/
class FileArchiveComponent extends Object {
var $_zip;
function __construct() {
$this->_zip = new ZipArchive();
}
function compress($fileName, $from) {
$filePath = $from . $fileName;
if ($this->_zip->open($filePath, ZIPARCHIVE::CREATE) !== true) {
exit(__('Cannot open') . " <{$fileName}>\n");
}
$this->_compress($from, $from);
$this->_zip->close();
return $filePath;
}
private function _compress($base, $from) {
if (!is_dir($from)) {
return false;
}
if ($handle = opendir($from)) {
while (false !== ($file = readdir($handle))) {
if ('.' == $file || '..' == $file || '.svn' == $file) {
continue;
}
$path = $from . DS . $file;
$add = str_replace($base . DS, '', $path);
if (is_dir($path)) {
$this->_zip->addEmptyDir($add);
$this->_compress($base, $path); // 再帰
}else if (is_file($path)) {
$this->_zip->addFile($path, $add);
}
}
closedir($handle);
}
}
}
★scaffold
scaffoldとは、データベースを利用するための基本機能を自動的に生成し表示する機能
コントロール
class SampleController extends AppController {
public $scaffold;
}
モデル
class Sample extends AppModel {
}
DDL
create table samples (...);
★CRUDサンプルコード
コントロール
class SampleController extends AppController {
public $name = "Sample"; // 省略可
public $uses = "Sample"; // 省略可
public $autoRender = true; // 省略可
public $autoLayout = true; // 省略可
public $layout = "sample";
function index(){
//検索
if (!empty($this->data)){
$target = $this->data["Sample"]["search"];
//キーで検索
$datas = $this->Sample->findAllById($target);
//完全一致
//$datas = $this->Sample->findAllByName($target);
//部分一致
// $datas = $this->Sample->find("all",
// array("conditions" => array(
// "Sample.name like ?" => array(
// "%{$target}%"))));
} else {
$datas = $this->Sample->find("all");
}
$this->set("datas", $datas);
//削除
if (!empty($this->data)){
$this->Sample->deleteAll(
array("Sample.id" => $this->data["Sample"]["delete"]));
}
$datas = $this->Sample->find("all");
$this->set("datas",$datas);
}
//追加
function add(){
if (!empty($this->data)){
$this->Sample->save($this->data);
if ($this->Sample->validates()){ //入力チェック
$this->redirect(".");
}
}
}
//更新
function edit(){
if (!empty($this->data)){
$this->Sample->save($this->data);
if ($this->Sample->validates()){ //入力チェック
$this->redirect(".");
}
} else {
$id = $this->params["url"]["id"];
$this->data = $this->Sample->findById($id);
}
}
}
findAllBy項目 検索されるすべてのデータを返す、findなどと同様
findBy項目 検索された最初の一行だけを返す、配列ではなく
モデル
class Sample extends AppModel {
public $validate = array(
"name" => array(
"rule" => 'notEmpty',
"message" => "xxx"
),
"mail" => array(
"rule" => 'mail',
"message" => "xxx"
),
"comment" => array(
"rule" => array("between", 0, 140),
"message" => "xxx"
)
);
}
ビュー index.ctp
<?php
echo $form->create("Sample", array('type'=>'post', 'action'=>'./index'));
echo $form->input("search");
echo $form->end("検索");
?>
<?php
echo $form->create("Sample", array('type'=>'post', 'action'=>'./index'));
echo $form->input("delete");
echo $form->end("削除");
?>
<table>
<tr><th>名前</th>...<th>XXX</th></tr>
<?php foreach($datas as $data){ ?>
<tr>
<td><?php echo $data['Sample']['name']; ?></td>
...
</tr>
<?php } ?>
</table>
<pre>
<?php print_r($datas); ?>
</pre>
ビュー add.ctp
<?php
echo $form->create("Sample", array("type"=>"post", "action"=>"./add"));
echo $form->input("name");
...
echo $form->textarea("comment");
echo $form->error("comment");
echo $form->end("追加");
?>
$form->inputでは、エラーメッセージまで自動で表示
それ以外のメソッドではそういう機能はない
ビュー edit.ctp
<?php
echo $form->create("Sample", array("type"=>"post", "action"=>"./edit"));
echo $form->input("name");
...
echo $form->textarea("comment");
echo $form->error("comment");
echo $form->end("更新");
?>
★Ajaxについて
class SampleController extends AppController {
function detailList() {
// Ajaxを利用する場合
$this->layout = "ajax";
// do something
// ビューに渡す
$this->set("resultArray", $result);
}
}
// Ajaxを利用しない場合
$this->autoRender = false;
// $this->layout = "ajax";
detail_list.ctp(ビュー) 通信用のJSONデータ
({<?php
foreach($resultArray as $key => $value){
// do something
}
echo $jsonString;
?>})