ざっくりCakePHP2.×入門

# 書いてる人
プログラミング学習サービスやら、ペットサロン予約サービス、風俗検索サービスなど色々とやっている「かずきち」です。
■運営サービス一部
http://crazy-wp.com/
http://webukatu.com/
新宿のホストから不動産・保険の営業を経て、HTMLって何？という状態から３ヶ月独学でプログラミングやデザインを学び、IT業界で１年間実務経験を積んで年収は１本超え。現在は起業家としてサービス運営やら不動産運営をしています。
Qiita内にそれ系の記事も書いてます。
<a href="http://qiita.com/kazukichi/items/7379b75fba2f90d3cf45" target="_blank">エンジニアで稼ぐために大切な１３のコト</a>
<a href="http://qiita.com/kazukichi/items/aeba286c2a750081e5c0" target="_blank">WEBサービスで起業したい人に読んで欲しい１８のコト</a>


#<a name="first">はじめに</a>
##CakePHPってなに？
PHPで効率的にWEBサービスやシステムを作るために開発されたフレームワーク（骨組み）。

##フレームワークってなに？
HTMLにそのままPHPを書いていると同じ記述が増えて非効率だったり、「サイトに表示する部分」と「内部の処理」とがごっちゃになってしまい分かりにくい。
しかも、複数人で開発をしていると同じ処理でも記述の仕方が人それぞれ違ったりするので統一性がない。
なので、何行もある同じ記述を１行で済むようにしたり、処理と表示を分けて考える「MVCモデル」という設計手法（考え方）に基づいて作られたのがフレームワーク。
「アプリケーションを作る土台」みたいなもの。

##MVCってなに？
PHPなどでプログラムをそのままゴリゴリ書いているものを３つに分類して分けて記述していく考え方。
###モデル（model）
アプリケーションが扱うデータやビジネスロジックを担当。
データーベースに対する処理やそれ以外の計算や処理をモデルの中に実装し、コントローラーやビューにその結果を提供する。

###ビュー（view）
ユーザに対しての見た目を担当。
Webアプリケーションの場合はHTMLやJavaScriptなどブラウザに対するユーザインタフェースを提供する部分で、HTMLやJSに関する処理は極力ビューで行う。

###コントローラー（controller）
ユーザからの入力を受け取り、処理を行う部分。webアプリケーションにおいてはユーザからの入力に応じてモデルを呼び出し、その結果をビューを呼び出してユーザに表示するという司令塔の役割。

#導入の仕方

googleで検索する。

#<a name="howto">実際の使い方</a>
モデル、ビュー、コントローラーのファイルをそれぞれ作って使う。

##コントローラーの作り方
コントローラファイルを作る場所： `app/Controller` 
ファイル名： `アプリケーション名Controller.php` 
※アプリケーション名は適当に「Site」とかで。

コントローラーにクラスを定義する。以下のような形で記述する。

```php
<?php

//CakePHPに用意されているライブラリをロードする。
//CakePHPではさまざまな機能が用意されているので、それらを利用する場合にApp:usesを使う。
//書き方はApp::uses( クラス名 , パッケージ名 );
//AppControllerを継承するためにControllerパッケージを読み込む

App::uses('AppController', 'Controller');

class コントローラー名 extends AppController {    //AppControllerを継承して使う
      public function アクション名1() {         
                                     ……ここに処理を書く……     
                                          }
      public function アクション名2() {         
                                     ……ここに処理を書く……     
                                          }
}
```

アクション１つが、WEBページの１ページになる。以降で、そのアクションに対応するViewを作成する。
ページを増やす時にはアクションを１つ増やしてあげる。

`$this->set("title_for_layout","サンプルサイト");` はサイトタイトルを設定するもの。第２引数にサイト名を入れる。

記述したら保存し、Webブラウザから以下のアドレスにアクセスしたら見れる。

```
http://localhost/[cakephpディレクトリ]/sample/
```

※普通ならindexアクションにアクセスするには「〇〇/sample/index」となるはずが、
CakePHPではindexがデフォルトのアクションに設定されてるので、
アクション名が省略されると自動的にindexアクションにアクセスしたものとみなされる。


URLの中身は以下のようになっている。

```
http://ドメイン名/cakeのフォルダ名/コントローラー名/アクション名/
```



##ビューファイルの作り方

###１．app/Viewフォルダ内に○○フォルダを作成する
○○の部分は「コントローラー名と同じ名前」にする。
SampleControllerなら「Sample」という名前のフォルダを作る。

###２．作ったフォルダの中に「○○.ctp」ファイルを作成する
○○の部分は「アクション名と同じ名前」にする。
indexなら「index.ctp」というファイルを作る。
この「.ctp」ファイルが各アクションに対応付けられたビューになる。


###３．index.ctpに普通にhtmlを記述

```html
<html>
  <head>
    <titile>Sample</titile>
  </head>
  <body>
    <h1>sample Page</h1>
    <p>test sample page</p>
  </body>
</html>
```

##モデルファイルの作り方
###1．データベースを作成する
データベース、テーブル、カラムを普通通り作成。
データベース名はアッパーキャメルケース（「SampleList」など単語ごとに先頭大文字にする記法）で。
テーブル名は「sample_tables」などとスネークケースでさらに複数形にする。

###2．データベース設定ファイルに追記する
データベースアクセスに関しての基本情報が入っている `app/Config/database.php` を開き
MySQLであれば以下のように記述する。

```php
<?php
class DATABASE_CONFIG {
     public $default = array(
        'datasource' => 'Database/Mysql',  //MySQL使うならこう書く
        'persistent' => false,  //持続接続のための設定。通常はfalseでいい
        'host' => 'localhost',  //ローカル環境ならlocalhost
        'login' => 'root',  //ユーザ名（今回の場合は管理者）
        'password' => '',   //パスワード
        'database' => 'MySampleData',  //作成したDB名
        'encoding' => 'utf8'
    );
}
?>
```
※設定内容を連想配列で記述していく

`http://localhost/CakePHPフォルダ名/` を開き一番下の項目に「Cake is able to connect to the database.」と緑色で表示されていれば、接続OK。

###3．モデルファイルを作成する
`app/Model` の中にファイルを作成する。
ファイル名：テーブル名と同じ（アッパーキャメルにして、単数形へ）.php
`sample_tables`なら`SampleTable.php`にする

ファイル名と同じ空のクラスを作って終わり。

```php
<?php
App::uses('AppModel', 'Model');
class SampleTable extends AppModel {
}
?>
```

###4.データベースへアクセスするコントローラーを作成する
作成ファイル場所：app/Controller
作成ファイル名：モデルファイル名の複数形+Controller.php（MySampleDatasController.php）

```
$datas = $this->MySampleData->find('all');
$this->set('datas',$datas);
```
※あとはビューでコントローラーから渡された変数datasをforeachで取り出す。
データ構造：$data['テーブル名（アッパーキャメル、単数形）']['カラム名'];

#<a name="send">コントローラーとビューの間で値を受け渡す</a>

コントローラーのアクション内に以下を記述。

```
$this->set( 変数名 , 値 );
```

```:例
$this->set('test','これはテストです');
```

そうすると、ビュー側に自動的に指定した変数（今回だと「test」）が用意され、そこに値が入っているので
ビュー側で「$test」を使って色々やればいい。


#<a name="helper">便利な機能「ヘルパー」</a>
cakephpにはWEBページを作る上での便利な機能（ヘルパー）がいろいろある。

##フォームヘルパー
htmlのformを簡単に作れる機能。

```php:viewファイルへの記述例
<h1>いま何時？</h1>
<?php
   //createでフォームを宣言
   echo $this->Form->create('Aisatsu',array(
      'type' => 'post', //type属性を指定
      'url' => 'show' 
      //↑アクションを指定。submitが押されるとこのアクションへ値が渡される。今回の場合、showアクションへ値が渡る。
   ));

   //inputでフォーム作成。type属性を指定すればいろいろなフォームが作れる。無指定だとtextになる。
   echo $this->Form->input('Aisatsu.zikan',array(
      'label' => '時間'
   ));

   //submitボタン作成
   echo $this->Form->submit();

   //フォーム宣言終わり。書かなくてもいい。
   echo $this->Form->end();
?>
```
※このままだとフォームごとに改行されて並ぶので、
フォームを横並びにしたいなら横並びにしたいformのarrayに
`‘div’=> falseと’label’=> false`
を入れてあげる。


###モデルで値を判断する
App/Modelフォルダに適当な名前のphpファイルを作る。
今回は「Sample.php」

```php:Sample.php
<?php
class Sample extends Model{

   public $name = 'Sample'; //クラス名を指定

   //DBのどのテーブルを使用するかを指定。使わないならfalseにしておく。
   public $useTable = false;

   public function judge($time){
      if($time == '朝'){
        $msg = 'おはよう';
      }elseif($time == '夜'){
        $msg = 'こんばんは';
      }
      return $msg;
   }

}

?>
```

###コントローラーで値を受け渡す
ビューから入力された値をまずコントローラーで受け取り、値を判断したのち、指定のアクションへ渡す。
CakePHPではフォームデータは　$_POST　ではなく $this->request->data　という形で受け取る。

```php:コントローラーファイルの記述例
function show(){
   //POSTが送信されたかどうか
   if($this->request->is('POST')){
     $time = $this->request->data['Aisatsu']['zikan']; //送信データを受け取る
     $msg = $this->Sample->judge($time); //モデルのメソッドを記述。返り値を保存。
     //ビューに値を渡す。引数１で受け渡した側で使える変数名を指定。引数２で受け渡す値を指定。
     $this->set('say',$msg);  //今回だとビューファイルでは$sayという変数に値が入って渡される。
   }
}
```

#<a href="layout">レイアウト（layout）の切り替え</a>
個々のページにはデフォルトのレイアウトが適用されている。
レイアウトは、画面にヘッダー・コンテンツ・フッターといった領域を設け、このコンテンツ部分に指定のビューをはめ込んで表示している。
このレイアウトを変更したい場合には以下のようにする。
※デフォルトのレイアウトを修正してもいい

１．app/View/Layoutsフォルダ内に「適当な名前.ctp」というファイルを作成する
２．作ったファイル内に以下のように記述

```html+php
<!DOCTYPE html>
<html>
<head>
    <?php echo $this->Html->charset(); ?>
    <title>
        <?php echo $title_for_layout; ?>
    </title>
    <?php
        echo $this->Html->meta('icon');
        echo $this->Html->css('Sample'); //適用するCSSファイル名を指定。今回の例だと「Sample.css」
        echo $this->fetch('meta');
        echo $this->fetch('css');
        echo $this->fetch('script');
    ?>
</head>
<body>
    <div id="container">
        <div id="header">
            <h1>My Board Application</h1>
            <h2>hello</h2>
        </div>
        <div id="content">
            <?php echo $this->Session->flash(); ?>
            <?php echo $this->fetch('content'); ?>
        </div>
        <div id="footer">
        </div>
    </div>
    <?php //echo $this->element('sql_dump'); ?>
</body>
</html>
```

３．app/webroot/cssフォルダ内に２で指定したcssファイルを作る。
（今回の例だと「Sample.css」）
４．作ったCSSファイルの中を普通のCSSと同じ様に記述していく。

５．コントローラーに適用するスタイルを指定する

```php
<?php
 class SampleController extends AppController{
    public $name= "Sample";
    public $components = array('DebugKit.Toolbar');
    public $layout = "Sample"; //適用するスタイルを指定。今回だと「Sample.ctp」のスタイルを適用
 
    public function index(){//アクション
    }
 }
```

#<a href="element">ビュー（View）ファイルを切り分ける「element」</a>
普段PHPでごりごり書く時にもヘッダー、フッターなどどのページでも同じ部分はファイルを分けて、そのファイルをincludeなどで読み込むが、同じ様にCakePHPではelementという機能でファイルを分けることができる。

切り分けは普通のPHPで書く時と同じように流用部分を分ける。
分けたファイルを読み込む時には

```php
echo $this->element('読み込むviewファイル名',array('data' => $data, 'mes' => 'こんにちは'));
```

を記述。
arrayで読み込む先のファイルへデータ受け渡しが可能。
普通のphpだとincludeなどした場合には変数はどっちのファイルでも共通で使えるが、CakePHPの場合は引数で渡さないと使えない。


#CakePHPでのバージョンによる違い

##POST/GETの受け取り方の違い
CakePHP1.～のものは

```php
//GETの場合
$this->params['url']['data'];

//POSTの場合
$this->params['form']['data'];
```

CakePHP2.～のものは

```php
//GETの場合
$this->request->query['data'];

//POSTの場合
$this->request->data['data'];
```
そのほか、1.～で `$this->data` として使ってたところは `$this->request->data`　になった。


#<a name="redirect">リダイレクトとフォワード</a>
リダイレクトは、AppControllerの「redirect」メソッドを使って行える。
リダイレクト先のアドレスを渡すだけ。
`$this->redirect( アドレス );`
もし、密かに別のアクションに処理を送りたければ、「フォワード（サーバー内で別アドレスの内容を結果として出力する）」という操作をする。

```php
$this->setAction( アクション名 );
<?php
App::uses('AppController', 'Controller');
class SampleController extends AppController {
    public function index() {
        $this -> autoRender = false;
        $this->redirect("./other/");
    }

    public function other(){
        $this -> autoRender = false;
        echo "<html><head></head><body>";
        echo "<h1>サンプルページ</h1>";
        echo "<p>これはもう１つのページです。</p>";
        echo "</body></html>";
    }
}

//別のアクションへのフォワード
public function index() {

    $this -> autoRender = false;
    $this->setAction("other");

}
```

#<a name="sanitize">サニタイズ</a>
サニタイズは、CakePHP2.0にライブラリとして用意されている。
サニタイズの方法は、クラスにいくつものメソッドとして用意されている。


```php:例
<?php
App::uses('AppController', 'Controller');
App::uses('Sanitize', 'Utility'); //サニタイズを使うためのライブラリ読み込み

class SampleController extends AppController {

  public function index() {}
  public function form() {
    $text1 = $this -> data["text1"];
    $check1 = isset($this -> data["check1"]) ? 
      "On" : "Off";
    $radio1 = $this -> data["radio1"];
    $this -> set("text1", Sanitize::stripAll($text1));  //サニタイズする
    $this -> set("check1", $check1);
    $this -> set("radio1", $radio1);
  }
}
```
※`Sanitize::stripAll`を指定した場合、引数に渡したテキストからホワイトスペース、スクリプト、イメージ、スタイルシートなどの情報を全て取り除いて無効化する。

#画像ファイルを読み込ませる
cssとほぼ同じ。例えば、test.jpgを読み込ませたい場合は、

```php
<?php echo $this->Html->image('logo.jpg',array('alt' =>'ZAKKRYトップページへ'); ?>
```

と記述。
画像は「/app/webroot/img/test.jpg」に配置する。

#画像読み込み＋画像にリンクを付ける

```php
<?php echo $this->Html->link($this->Html->image('logo.jpg',array('alt' =>'ZAKKRYトップページへ')), '', array('escape' => false)); ?>
```
`‘escape’ => false` をしないと、imgタグの < や > が＆lt;、＆gt;に変換されてしまい、画像が表示されない。


#外部jsファイルを読み込む

##１．jsファイルを置く
jsファイルの置き場所：/app/webroot/js
##２．Controllerに１行記述
使いたいactionに以下の１行記述

```php
var $helpers = array('Javascript');
```

##３．Viewに１行記述
link('')内にjsファイル名を記述する

```php
<?php echo $javascript->link('test'); ?>
```

...続く



#WEBプログラミングから起業までを一貫して学べるオンライン動画総合学習サービス『ウェブカツ！！』
様々なプログラミング学習サイトやサービスでは正直な所、自分でWEBサービスを作れるようにはならないため、「自分でWEBサービスを作れるようになる！」をゴールとしたオンライン動画総合学習サービス『ウェブカツ！！』を立ち上げました。ご興味ある方は登録よろしくお願いいたします。
http://webukatu.com/