公式サイト 公式ドキュメント API 公式チュートリアル

目次

  1. CakePHP3の概要
  2. インストール手順
  3. 最初のDB設定
  4. POSTの基本
  5. Sql Logなどのデバッグ情報を確認する方法
  6. CakePHP3の命名規則について
  7. バリデーションの基本
  8. DBからデータを取得し一覧表示 | find
  9. LEFT JOIN
  10. 基本的なDB保存
  11. 複数データのDB保存
  12. Entityクラス | モデル

CakePHP3の概要

CakePHP3はPHP5.5.9以上で動作する。
また、php_intl.dllが必要。

Composerでインストールすることが推奨されているが、zip形式でのダウンロード も可能である。
なお、Composerでインストールするときは、php.iniを開き「php_intl.dll」を有効にする必要がある。

CakePHP2.X系との相違点

フォルダや設定ファイルの名前が変わっている。

インストール手順

以下の手順はファイル一式をダウンロードして展開する方法。

手順

  1. PHPのバージョンが5.5.9以上であることを確認する。
  2. php.iniをテキストエディタで開き、「;」を外して「extension=php_intl.dll」を有効にする。
  3. GithubからCakePHP3をダウンロードする。
    CakePHP3のダウンロードサイト
  4. ダウンロードファイルを解凍し、解凍したファイル一式をApacheのルートティレクトリ(htdocs)に配置する。
  5. フォルダ名をプロジェクト名に変えて、Eclipseに新プロジェクトとして認識させる。
  6. 「http://localhost/cake3_demo」にアクセスして、CakePHPの画面が表示されたら、インストールは成功である。

最初のDB設定

CakePHP2系にあった「database.php」は、CakePHP3に存在しない。
代わりに「config/app.php」にDB設定を記述する。

DB設定の方法

configのapp.phpファイルを開く。
「Datasources」項目のdefaultを以下のように修正する。

app.php
	  ~ 省略 ~      
	
    'Datasources' => [
        'default' => [
            'className' => 'Cake\Database\Connection',
            'driver' => 'Cake\Database\Driver\Mysql',
            'persistent' => false,
            'host' => 'localhost',
            /**
             * CakePHP will use the default DB port based on the driver selected
             * MySQL on MAMP uses port 8889, MAMP users will want to uncomment
             * the following line and set the port accordingly
             */
            //'port' => 'non_standard_port_number',
            'username' => 'root',
            'password' => 'xxx',
            'database' => 'cake_demo',
            'encoding' => 'utf8',
            'timezone' => 'UTC',
            'flags' => [],
            'cacheMetadata' => true,
            'log' => false,
            
	  ~ 省略 ~      
	


CakePHP3をインストール直後のトップ画面でDB接続が成功したかどうかが分かる。


POSTの基本

POSTの基本的ソースコードである。
index画面のデータをPOSTでreg画面に送る。

コントローラ


	<?php

	namespace App\Controller;
	
	class AnimalController extends AppController
	{
	
		public function index(){
	
		}
		
		public function reg(){
			$animal_name = $this->request->data['animal_name'];
			$this->set(array(
					'animal_name'=>$animal_name
			));
		}
	}
	

ビュー

index.ctp

	<?php 
	echo $this->Form->create('Animal' , ['type'=>'post','url'=>['action'=>'reg']] );
	echo $this->Form->text('animal_name');
	echo $this->Form->submit('送信');
	echo $this->Form->end();
	?>
	

reg.ctp

	動物名:<?php echo $animal_name?>
	

画面の動き



CakePHP2との相違点

CakePHP2と似ていますが、異なる箇所があります。
「$this->Form->create」のurl属性の指定方法が変わった。
また、「$this->request->data[モデル名][フィールド]」となっていたが、モデル名が省かれ「$this->request->data[フィールド]」と簡略化された。

Sql Logなどのデバッグ情報を確認する方法

CakePHP3の命名規則について

テーブル名、コントローラ名、アクション名、モデル名、ビュー名、URLの命名規則は変わった。

テーブル名とモデル名(コントローラ名)の命名変更点

CakePHP2ではテーブル名は複数系、モデル名は単数形である。
複数形のテーブル名は英文のルールに従っており、単純に「s」を付ければいいわけではなかった。

CakePHP3からは複数形、単数形の違いがなくなった。
例えばテーブル名が「animals」ならモデル名およびコントローラは「Animals」「AnimalsController」である。

CakePHP2
DBテーブル名モデル名
big_catsBigCat
statusesStatus
fishFish
fishs英文の複数形ルールとして正しくないのでエラー(fishの複数形はfish)

CakePHP3
DBテーブル名モデル名
big_catsBigCats
statusesStatuses
fishFish
fishsFishs

アクション名の変更点

アクション名は必ずキャメル記法で記載しなければならなくなった。スネーク記法は禁止された。

正しいアクション名
function fishReg() {...

誤ったアクション名
function fish_reg() {...

ビュー名の変更

従来のビューはViewフォルダでなくTemplateに作成するようになった。
フォルダ名はコントローラおよびモデルと同じパターンである。
src/Template/OkinawaFishs/fish_reg.ctp

ビュー(ctp)のファイル名はスネーク記法である。キャメル記法やチェーン記法だとエラーになる。
アクション名がfishRegであるとき、ビューファイル名は「fish_reg.ctp」となる。

正しいビュー名
fish_reg.ctp

誤まり
fishReg.ctp
fish-reg.ctp

URLはチェーン記法で表されるようになった

http://localhost/cake3_demo/okinawa-fishs/fish-reg


サンプル

OkinawaFishsController (DBテーブル名:okinawa_fishs)
	<?php

	namespace App\Controller;
	
	class OkinawaFishsController extends AppController
	{
	
		public function index(){
	
		}
		
		public function fishReg(){
			$name = $this->request->data['name'];
			
			$ent = $this->OkinawaFishs->newEntity($this->request->data);
			$this->OkinawaFishs->save($ent);
			
			$this->set(array(
					'name'=>$name
			));
		}
	}
	



バリデーションの基本

基本的な方法として、バリデーション条件はテーブルクラスに記述する。
エンティティのerrorsメソッドを実行すると、バリデーションが実行され、入力エラー情報も取得できる。
saveを実行した時にもバリデーションが実行されているようであり、入力エラーがあるならDB保存されない。

DBテーブルと関連しないバリデーションをコントローラ内で組み込むことも可能である。 (参考:テーブルクラス不要のバリデーション


ソースコード

コントローラ:AnimalsController.php
	namespace App\Controller;
	use Cake\Validation\Validator;
	class AnimalsController extends AppController
	{
		public function index(){
			
		}
		
		public function reg(){
	
			$animal_name = $this->request->data['animal_name'];
	
			$ent = $this->Animals->newEntity($this->request->data);
			$errors = $ent->errors();
			if(empty($errors)){
				$this->Animals->save($ent);
			}
	
			$this->set(array(
					'animal_name'=>$animal_name,
					'errors'=>$errors
			));
		}
	}
	

テーブルクラス:AnimalsTable.php
	namespace App\Model\Table;
	use Cake\ORM\Table;
	use Cake\Validation\Validator;
	class AnimalsTable extends Table{

		public function validationDefault(Validator $validator)
		{
	
			$validator
				->notEmpty('animal_name','動物名は必須入力です。')
				->maxLength('animal_name', 4,'動物名は4文字以内です。')
			;
				
			return $validator;
		}
	
	}
	

ビュー:index.php
	<?php 
	echo $this->Form->create('Animals' , ['type'=>'post','url'=>['action'=>'reg']] );
	echo $this->Form->text('animal_name');
	echo $this->Form->submit('送信');
	echo $this->Form->end();
	?>
	

ビュー:reg.ctp
	<h2>CakePHP3 | Animal | reg</h2>
	
	動物名:<?php echo $animal_name?><br>
	<br>
	
	<p>バリデーション</p>
	<?php var_dump($errors)?>
	<br>
	

ファイル構造

バリデーションのファイル構造

挙動



DBからデータを取得し一覧表示 | find

コントローラ


	namespace App\Controller;
	use Cake\ORM\TableRegistry;
	
	class OkinawaFishsController extends AppController
	{
		public function fishList(){
			$okinawaFishs = TableRegistry::get('OkinawaFishs');
			$data = $okinawaFishs->getFishList1();
			$this->set(array(
					'data'=>$data
			));
		}
	}
	

テーブルクラス(モデル)


	namespace App\Model\Table;
	use Cake\ORM\Table;
	
	class OkinawaFishsTable extends Table
	{
	
		public function initialize(array $config)
		{
	
		}
		
		public function getFishList1(){
	
			$data = $this->find()->
				where(['fish_value'=>102])->
				order(['fish_date DESC'])->
				limit(10)->
				all();
	
			return $data;
			
		}
	
	}
	

テンプレート(ビュー)


	<table>
	<thead><tr><th>id</th><th>fish_name</th><th>fish_date</th><th>fish_value</th></tr></thead>
	<tbody>
	<?php 
	foreach ($data as $ent){
		echo "<tr><td>{$ent->id}</td>";
		echo "<td>{$ent->fish_name}</td>";
		echo "<td>{$ent->fish_date->format('Y-m-d')}</td>";
		echo "<td>{$ent->fish_value}</td></tr>¥n";
		
	}
	?>
	</tbody>
	</table>
	

LEFT JOIN

ソースコード


	$query = $this->find()
	->join([
			'OkinawaFishs' => [
					'table' => 'okinawa_fishs',
					'type' => 'LEFT',
					'conditions' => 'FishingRecs.fish_id = OkinawaFishs.id',
			],
	]);
	
	$query->select([
			"id"=>"FishingRecs.id",
			"catch_count"=>"FishingRecs.catch_count",
			"fishing_rec_date"=>"FishingRecs.fishing_rec_date",
			"fish_name"=>"OkinawaFishs.fish_name",
	]);

	$data = $query->all();
	

SQLログ


	SELECT 
	  FishingRecs.id AS `id`, 
	  FishingRecs.catch_count AS `catch_count`, 
	  FishingRecs.fishing_rec_date AS `fishing_rec_date`, 
	  OkinawaFishs.fish_name AS `fish_name` 
	FROM 
	  fishing_recs FishingRecs 
	  LEFT JOIN okinawa_fishs OkinawaFishs ON FishingRecs.fish_id = OkinawaFishs.id
	


基本的なDB保存

配列データをnewEntityでエンティティに変換してから、saveでDB保存する。
エンティティはオブジェクト型である。

モデル名について

テーブル名がanimalsである場合、モデル名は「Animals」である。
CakePHP2と同様、モデルクラスを作らなくてもモデルを使用できる。
モデルクラスを作成していない場合、内部的にテーブル名からモデルを自動生成している。

サンプル

	namespace App\Controller;
	class AnimalsController extends AppController
	{
		public function reg(){
			$data=array('animal_name'=>'タヌキ');
			$ent = $this->Animals->newEntity($data);
			$this->Animals->save($ent);
	
		}
	}
	

animalsテーブル

idanimal_nameanimal_valueanimal_datemodified
3タヌキNULL0000-00-002016/6/23 10:53
CakePHP2と同様、idを省略すればINSERTとされ、idを指定すればUPDATEになる。



複数データのDB保存

CakePHP3ではsaveAllが廃止されてしまった。
代わりに、配列データからnewEntitiesでエンティティリストを作成し、ループしながらエンティティを保存する方法になった。
この方法にトランザクションを組み入れることも可能である。

	namespace App\Controller;
	class AnimalsController extends AppController
	{
		public function reg(){
			$data=array(
					array('animal_name'=>'オオカミ'),
					array('animal_name'=>'クマ'),
			);
			
			$animals = $this->Animals->newEntities($data);
			
			$this->Animals->connection()->begin();//トランザクション開始
			
			foreach ($animals as $animal) {
				$this->Animals->save($animal);
			}
			
			$this->Animals->connection()->commit();//コミット
	
	}
	

animalsテーブル

idanimal_nameanimal_valueanimal_datemodified
12オオカミNULL0000-00-002016/6/23 12:55
13クマNULL0000-00-002016/6/23 12:55


Entityクラス | モデル

2.xまでのModelクラスは、3.xではTableクラスとEntityクラスに分離される。
Tableクラスは2.x系のModelクラスと同様な働きであるが、 Entityクラスは行とプロパティに特化したクラスである。
DBの行を取得、編集、追加するときに使われる。
Tableクラスのfind()で取得したデータの行要素はEntityクラスになっている。
Eager ローディングとLazy ローディングという概念もある。

Entityクラスでできること

  1. アクセサー(Getter)とミューテーター(Setter)をカスタマイズできる。
  2. テーブルには存在しない仮想フィールドを作ることができる。(アクセサーカスタマイズの応用)
  3. エンティティが変更されたかどうかが分かる。
  4. フィールド単位でバリデーション(エラー情報)を取得することができる。
  5. 一括代入ができる。また、一括代入を禁止するプロパティを定義することも可能。
  6. エンティティが示す行がデータベース上にすでに存在するかチェックする。
  7. 複数のエンティティクラス間で共通するロジックを使う場合、トレイトという仕組みがある。
  8. エンティティから配列や JSON への変換できる。(変換するプロパティを定義することも可能)

リンク

公式ドキュメント