72
8時間耐久CakePHP / Yusuke Ando (@yando) CakePHP2 8時間耐久 第1回 下北沢CakePHP / Yusuke Ando (@yando)

8時間耐久CakePHP2 勉強会

  • Upload
    yandod

  • View
    20.242

  • Download
    2

Embed Size (px)

DESCRIPTION

8時間耐久CakePHP2勉強会の資料。 http://blog.candycane.jp/archives/1200

Citation preview

Page 1: 8時間耐久CakePHP2 勉強会

8時間耐久CakePHP / Yusuke Ando (@yando)

CakePHP28時間耐久

第1回 下北沢CakePHP / Yusuke Ando (@yando)

Page 2: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

本日の主旨8時間という長尺CakePHPの基本

骨の髄に(強制的に)刻みこむ(@shinichiNに)

Page 3: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

who am I

Page 4: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

本日のメニューMVCの考え方

セットアップの肝コントローラーの使い方

モデルの使い方ビューの使い方応用技の紹介

Page 5: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

MVCの考え方by crabchick

Page 6: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

MVCだらけ

Page 7: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

なぜMVC

複雑化するプログラム整理が必要分割の経験則

Model View Controller

Page 8: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

MVCに分割

巨大なプログラム

Page 9: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

MVCの役割

•Model  データや処理(データベース処理)

•View  見た目を担当(HTMLの出力)

•Controller  入力を受けてモデルとビューを呼ぶ(それ以外)

Page 10: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

CakePHPの前に

ふつうのPHPスクリプトで考えてみます

Page 11: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

<?php

$keyword = '';

if (isset($_POST['keyword'])) {

$keyword = $_POST['keyword'];

}

mysql_connect('localhost','user','password');

mysql_select_db('cakephp_sample');

mysql_query('set names utf8');

$sql = sprintf(

"SELECT id,name,description FROM friends WHERE name LIKE '%s'",

mysql_real_escape_string('%'.$keyword.'%')

);

$result = mysql_query($sql);

$data = array();

while ($row = mysql_fetch_assoc($result)) {

$data[] = $row;

}

?>

<html>

<head><title>テストページ</title></head>

<body>

<form action="list1.php" method="POST">

<input name="keyword"><input type="submit">

</form>

<ul>

<?php

foreach ($data as $row) {

echo '<li>';

echo $row['name'];

echo $row['description'];

echo '</li>';

}

?></ul>

</body></html>

Page 12: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

<?php

$keyword = '';

if (isset($_POST['keyword'])) {

$keyword = $_POST['keyword'];

}

mysql_connect('localhost','user','password');

mysql_select_db('cakephp_sample');

mysql_query('set names utf8');

$sql = sprintf(

"SELECT id,name,description FROM friends WHERE name LIKE '%s'",

mysql_real_escape_string('%'.$keyword.'%')

);

$result = mysql_query($sql);

$data = array();

while ($row = mysql_fetch_assoc($result)) {

$data[] = $row;

}

?>

<html>

<head><title>テストページ</title></head>

<body>

<form action="list1.php" method="POST">

<input name="keyword"><input type="submit">

</form>

<ul>

<?php

foreach ($data as $row) {

echo '<li>';

echo $row['name'];

echo $row['description'];

echo '</li>';

}

?></ul>

</body></html> Viewへ

Modelへ

Page 13: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

<?php

//index.php

$keyword = '';

if (isset($_POST['keyword'])) {

$keyword = $_POST['keyword'];

}

include ‘model.php’;

include ‘view.php’;

<?php

//model.php

mysql_connect('localhost','user','password');

mysql_select_db('cakephp_sample');

mysql_query('set names utf8');

$sql = sprintf(

"SELECT id,name,description FROM friends WHERE name LIKE '%s'",

mysql_real_escape_string('%'.$keyword.'%')

);

$result = mysql_query($sql);

$data = array();

while ($row = mysql_fetch_assoc($result)) {

$data[] = $row;

}

<!-- view.php -->

<html>

<head><title>テストページ</title></head>

<body>

<form action="list1.php" method="POST">

<input name="keyword"><input type="submit">

</form>

<ul>

<?php

foreach ($data as $row) {

echo '<li>';

echo $row['name'];

echo $row['description'];

echo '</li>';

}

?></ul>

</body></html>

Model

View

Controller

Page 14: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

別々にしただけ

Page 15: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

CakePHPのMVCController置き場(全ての起点)

Model置き場(データベース関連)

View置き場(HTML関連)

Page 16: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

CakePHP習得の為に

Controllerの知識Modelの知識Viewの知識

それぞれの理解を深める

Page 17: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

セットアップの肝

Page 18: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

ポイントpdo_mysqlmod_rewritePHP5.2以上

core.php / database.phpchmod -R 777 app/tmp

Page 19: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

phpinfo()

Page 20: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

mod_rewriteが無い

Page 21: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

rewrite無しの場合/** * To configure CakePHP *not* to use mod_rewrite and to * use CakePHP pretty URLs, remove these .htaccess * files: * * /.htaccess * /app/.htaccess * /app/webroot/.htaccess * * And uncomment the App.baseUrl below: */ //Configure::write('App.baseUrl', env('SCRIPT_NAME'));

コメントを外す(rewriteが無理な時だけ)

Page 22: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

準備完了

Page 23: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

Controllerの使い方

Page 24: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

典型的なコントローラー<?php// app/Controller/TaskController.phpApp::uses('AppController', 'Controller');

class TasksController extends AppController { public function index() { $task_data = $this->Task->find(‘all’); $this->set(‘task_data’,$task_data); }}

Page 25: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

Controllerの必須テクディスパッチのルール$scaffold $uses$this->render()$this->set()

$this->redirect()$this->request

Page 26: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

ディスパッチ

アクセスされたURLに応じて適切なコントローラーを

呼び出す機構

Page 27: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

ページコントローラー

index.phpmenu.php

mypage.phpに直接URLからアクセス

(ふつうのPHP)

Page 28: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

フロントコントローラー

index.phpにまずアクセスして、

その中でそれぞれの処理に飛ばす

(CakePHPはこの方式)

Page 29: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

ディスパッチの例/tasks/index→TasksControllerのindex/Oden/umai→OdenControllerのumai/my_page→MyPageControllerのindex

Page 30: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

routes.phpなら

任意のマッピングも追加可能(最後にURLだけ変更とか)そのままでOKなら設定不要

Page 31: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

$scaffold

public $scaffold;とするだけで標準機能が動く

※動作確認などに便利

Page 32: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

$uses

コントローラーが使うモデルのリスト省略時はコントローラー名と同一

命名規則で苦しむのは横着するからです

class MyController extends AppController { public $uses = array(‘Task’,‘User’);

}

Page 33: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

$this->render()

任意のViewを呼び出す省略時はアクション名と同名を呼ぶ

同じViewを使いまわす事もできる!

$this->render(‘hoge’);

Page 34: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

$this->set()

任意のデータをViewへ渡すスカラー値も配列も渡せる

Viewで使いたいデータはset()!

$this->set(‘hoge’,‘this is data’);

Page 35: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

$this->redirect()

任意のページへリダイレクト$this->flash() や

$this->Session->setFlash()と組みわせてメッセージ表示

登録完了やエラー時によく使う

$this->redirect(‘oden/umai’);

Page 36: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

$this->request

フォームの入力内容などにアクセス可

$_POSTなどを使った者は校庭10周に処す

$this->request->data$this->request->pass$this->request->is()

Page 37: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

Modelの使い方

Page 38: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

典型的なモデル

<?php// app/Model/Task.phpApp::uses('AppModel', 'Model');

class Task extends AppModel { public $useTable = 'tasks';}

Page 39: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

Modelの必須テク$useTable

$primaryKeyfind()

save() saveField() updateAll() delete()

deleteAll()

Page 40: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

Modelの必須テク2

$validates$belongsTo

$hasOne / $hasMany$hasAndBelongsToMany

Page 41: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

Model手強い

Modelを制する者はCakeを制す

Page 42: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

$useTable

モデルが処理を行うテーブル名を指定省略時はモデル名の複数形になるfalseにするとテーブル無しモデル

ここもはまりやすい

public $useTable = ‘tablename’;

Page 43: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

$primaryKey

テーブルの主キーを設定省略時は’id’

既存のテーブルを使う場合に便利

public $primaryKey = ‘id’;

Page 44: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

$this->find(‘all’,$options);$this->find(‘first’,$options);$this->find(‘count’,$options);$this->find(‘list’,$options);

$this->find(‘threaded’,$options);$this->find(‘neighbors’,$options);

find()

オプション次第で自在にSQL文を実行

Page 45: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

find(‘all’) の結果$data = $this->Hoge->find(‘all’);

$data[0][‘Hoge’][‘name’]; // Hogeのname$data[0][‘Hoge’][‘twitter’]; // Hogeのtwitter

Page 46: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

array( 'conditions' => array('Model.field' => $thisValue), 'recursive' => 1, //int 'fields' => array('Model.field1', 'DISTINCT Model.field2'), 'order' => array('Model.created', 'Model.field3 DESC'), 'group' => array('Model.field'), 'limit' => n, 'page' => n, 'offset' => n, 'callbacks' => true)

find()のオプション

必要ない部分は適宜省略可能様々なfind()にこのオプションを使う

Page 47: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

array( 'conditions' => array('Model.field' => $thisValue), 'recursive' => 1, //int 'fields' => array('Model.field1', 'DISTINCT Model.field2'), 'order' => array('Model.created', 'Model.field3 DESC'), 'group' => array('Model.field'), 'limit' => n, 'page' => n, 'offset' => n, 'callbacks' => true)

find()のオプション

利用頻度が低いオプションは放置

Page 48: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

find(‘first’) の結果$data = $this->Hoge->find(‘first’);

$data[‘Hoge’][‘name’]; // Hogeのname$data[‘Hoge’][‘twitter’]; // Hogeのtwitter

Page 49: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

find(‘count’) の結果$data = $this->Hoge->find(‘count’);

数値で帰ってくる

Page 50: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

find(‘list’) の結果$data = $this->Hoge->find(‘list’);

リストで帰ってくる

Page 51: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

save()

渡されたデータを元にデータを保存INSERT/UPDATEに両対応主キーがあるかないかで分岐

Model->save($data,$validate = true);

Page 52: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

saveField()

単一のフィールドを更新しかしあまり使わない

(save()で同じ事ができる)

Model->id = $id;Model->saveField($name,$value);

Page 53: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

updateAll()

条件にマッチするデータを全て更新あまり使わない

(データが少なければ1件づつsave()でも問題ないので)

Model->updateAll($fields,$condition);

Page 54: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

delete() deleteAll()

DELETEを実行できる。しかし実際のシステムでDELETEは使わず削除フラグなどで操作する事が多い。

Model->delete($id,$cascade);Model->deleteAll($condition,$cascade);

Page 55: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

$validates

配列で設定したとおりに検査save前に実行される

public $validate = array( 'twitter' => array( 'rule' => 'notEmpty', 'message' => 'Twitter is very important' ), 'name' => array( 'rule' => 'notEmpty', ) );

Page 56: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

アソシエーション

$belongsTo$hasOne / $hasMany

$hasAndBelongsToMany

Page 57: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

$belongsTo

モデルが属する上位モデルを指定日記(たくさん) ー> ユーザー(1)

public $belongsTo = array( 'Shimokita' => array( 'foreignKey' => 'friendlist_id' ));

Page 58: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

$hasMany

モデルが所有している下位モデルを指定ユーザー ー> 日記(たくさん)

public $hasMany = array( 'Item');

Page 59: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

Viewの使い方

Page 60: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

Viewの必須テクLayoutの変更$this->request$this->element()$this->Html$this->Form

Page 61: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

Layout

Page 62: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

Layoutの変更

ビューはレイアウトの中に読み込まれる

標準はlib/Cake/View/Layout/default.ctp

Page 63: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

Layoutの変更

Cakeディレクトリは変更してはいけない。コピーして使う

app/View/Layout/default.ctp

Page 64: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

$this->element

テンプレートから別のテンプレートを読み込む。

(変数はオプションで渡す)

echo $this->element(‘template’,$data);

Page 65: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

$this->Html

HTMLを生成するヘルパーURLを自動生成して便利(手動でタグは書かない)

$url = array( ‘controller’ => ‘hoge’, ‘action’ => ‘index’);echo $this->Html->link($title,$url);

Page 66: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

$this->Form

フォームを生成する初期値のフィルインや

エラーメッセージを自動化

echo $this->Form->create(‘ModelName’);echo $this->Form->input($fieldName);

Page 67: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

応用技の紹介

Page 68: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

CakePHPの応用技

MVCの各部品を強化標準の強力な機能群MVCの各要素に対応

例外もある

Page 69: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

MVC::BHC

ControllerModel

View

ComponentBehavior

Helper

Page 70: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

応用技に手を伸ばす時

コードが肥大化した時まずはHelper

次にComponent最後にBehavior

Page 71: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

まだある応用技

プラグインCoreクラスConsole

ユニットテスト

Page 72: 8時間耐久CakePHP2 勉強会

第1回 下北沢CakePHP / Yusuke Ando (@yando)

今後の羅針盤

http://book.cakephp.org/2.0/en/http://book.cakephp.org/2.0/ja/