Cake-phpの勉強メモ
2018年11月29日
Cake-phpは、MVCアーキテクチャで構成されているPHPのフレームワーク
MVCアーキテクチャとは、Model、View、Conrollerで分離されている、いわばSwiftのXcodeと似ている。
Configファイル
Model
View
最近のCake-php
昔に比べると下火になっているものの、現在でも使われている。
世界ではそこまで使われていないものの、日本国内では人気がある。
競合するPHPフレームワークとしては、Laravelなどがある。
Cake-PHPの導入
作業環境にLAMP環境が整っていることが前提。
まずは、インストールするためにComposerを導入する必要がある。
これは、PHPに関する各種ライブラリの依存関係を管理するためのツールなので、とりあえずCake-phpを導入するにあたって必要となる。
あればスムーズというか、例ではほぼ使っているのでほぼ必須といってもいいだろう。
実際にMacのローカル環境に導入してみた結果
Macのローカル環境で使えるApacheの環境にCakephpを導入してみた。
まずはComposerの導入だが、これは問題なく進む。
CakephpをApacheのテストディレクトリまで移動してプロジェクトを作成。
導入の時点でWarningが出ているが、とりあえず実行することができた。
作成したプロジェクトディレクトリを見てみると、Cake-phpのフレームワークのファイルが一式生成されている。
それで、サイトにアクセスしてみると、500エラー。
エラーログを見てみると、php-intl.soがないとかそういうかんじのエラーが出ていた。
phpの拡張機能でphp-intlが必要ということで、入れてみる。
まずは、Hombrewを使って、brew コマンドでインストールを試みるが、brewコマンドで昔はインストールできていたのだが、現在はできなくなっているらしい。
Macportsというパッケージ管理システムを使ったらインストールできるらしい。
Homwbrewがパッケージ管理でMacportsのパッケージ管理システムで、何がどう違うか分からないが、やってみるととりあえずMacportsのほうではインストールできた。
しかし、相変わらずcakephpのプロジェクトを作成し直してもエラー。
エラーを見ると、php-intl.dllがないということ。
調べると、場所に問題があるのが原因で移動したらいいということのようなので、php-intl.dllを探してみると、どこにもない。
そもそも、.dllファイルはWindows環境で必要なものらしく、MacのLinuxベースの環境では不要らしいのだが、とにかく動かないので駄目。
環境構築の時点でつまづいてしまい、お手上げ状態だったのだが、多くのケースでXAMPまたはMAMP環境が前提になっていたので、MAMP環境を入れてみたところ、あっさりと動いた。
※注
MAMPインストール後、PHPの動作環境を、MAMPのPHPに変更する必要があり。
MAMPとComposerを使ったCakePHP3.xのローカル開発環境の構築
MAMP環境では動いて、ローカルのMac環境では動かなかった、その違いは何なのかよく分からないが、とりあえず動いたのでOK。
チュートリアルで実装してみる
Cakephpの公式サイトのチュートリアルで実装してみる。
まず、モデルの部分
これは、データベースのテーブルごとの規約を書いているところ。
テーブルのカラムごとのバリデーション等を定義できる。
モデルには、Entitityオブジェクトと、Tableオブジェクトがある。
コントローラーは、サイトのURLの呼び出しに対して実行される実行内容と考えればいい。
/Controller/◯◯Controller.php
の場合、サイトURL/◯◯で呼び出される。
ビューは、Templateディレクトリの中で、URLの階層構造と同じようにディレクトリを設置して、作成する。
拡張子がctpというのが変わっているが、Smartyと違って独特の記法があるわけではなく、普通のphpファイルに近い。
しかし、phpのごちゃごちゃしたややこしい記述部分はControllerやModelの部分に映っているので記述は最低限のphpの部分だけになっていてhtmlがベースとなっている。
そのため、フロントエンドエンジニアの人がファイルの内容を見て修正したり内容を理解しやすいというわけだ。
Cakephpのライブラリのソースはどこにあるか
Cakephpで呼び出しているライブラリのソースコードは、以下の場所にありました。
/vender/cakephp/cakephp/src/
例えば以下のプログラムがあります。
//名前空間Cake\ORM以下のTable Registryクラスを省略 use Cake\ORM\TableRegistry; //Table RegistryクラスのgetTableLocatorメソッドは、'Cake\ORM\Locator\TableLocator'クラスのgetメソッドを実行します。ここではArticlesTableクラスを返します(Artices Tableクラスは、Tableクラスの拡張クラス) //Model→Tableに作成したテーブルクラスにアクセスできる $articles = TableRegistry::getTableLocator()->get('Articles'); //Table classのfind()メソッドを実行して$queryへ代入 //Articlesテーブルの行を全てselectで取り出す //findはselectと基本同じ $query = $articles->find(); //取得した行からqueryのtitleを出力 foreach ($query as $row) { //行の連想配列のtitleを出力する echo $row->title; }
それぞれのメソッドやクラスの意味を理解しようと思ったのですが、正直良くわからないので、おまじない的に覚えておいたほうがよさそうです。
(むしろ、そういうのをいちいち理解する必要がないのがフレームワークのいいところ?)
データベース接続
コネクションオブジェクトに対して
$connection->query($sql);
でsqlを実行できるが、パラメータは受け付けず、また、sqlインジェクションの危険性があるため危険
executeオブジェクトの使用を推奨。プリペアードステートメントが使用できる。
$connection->execute(‘SELECT * FROM articles WHERE id = :id’, [‘id’ => 1])->fetchAll(‘assoc’);
型に対してバインドすることも可能。
$connection
->execute(
‘SELECT * FROM articles WHERE created >= :created’,
[‘created’ => new DateTime(‘1 day ago’)],
[‘created’ => ‘datetime’]
)
->fetchAll(‘assoc’);
プリペアードステートメントは、prepareで準備してから別のところで当てはめることも可能。
$stmt = $conn->prepare(
‘SELECT * FROM articles WHERE published = ? AND created > ?’
);
// 複数項目のバインド
$stmt->bind(
[true, new DateTime(‘2013-01-01’)],
[‘boolean’, ‘date’]
);
// 1項目ずつのバインド
$stmt->bindValue(1, true, ‘boolean’);
$stmt->bindValue(2, new DateTime(‘2013-01-01’), ‘date’);
newQuery()メソッドでクエリオブジェクトを生成して、クエリビルダを使用することも可能。
$connection
->newQuery()
->select(‘*’)
->from(‘articles’)
->where([‘created >’ => new DateTime(‘1 day ago’)], [‘created’ => ‘datetime’])
->order([‘title’ => ‘DESC’])
->execute()
->fetchAll(‘assoc’);
connectionオプジェクトから、insert文とupdate、delete文を実行できる
$connection->insert(‘articles’, [
‘title’ => ‘A New Article’,
‘created’ => new DateTime(‘now’)
], [‘created’ => ‘datetime’]);
$connection->update(‘articles’, [‘title’ => ‘New title’], [‘id’ => 10]);
use Cake\Datasource\ConnectionManager;
$connection = ConnectionManager::get(‘default’);
取得した行をを配列に読み込む
// 1行読み込む
$row = $stmt->fetch(‘assoc’);
// 全行を読み込む
$rows = $stmt->fetchAll(‘assoc’);
行数を取得する
$rowCount = count($stmt);
$rowCount = $stmt->rowCount();
エラー情報の取得
$code = $stmt->errorCode();
$info = $stmt->errorInfo();
トランザクションを利用する場合は、コネクションオブジェクトからbeginとcommitを使用することで利用できる。
$conn->begin();
$conn->execute(‘UPDATE articles SET published = ? WHERE id = ?’, [true, 2]);
$conn->execute(‘UPDATE articles SET published = ? WHERE id = ?’, [false, 4]);
$conn->commit();
命名規則
cakephpでは、基本的にはコントローラー、モデル、ビューに命名規則があり、それに従って作成していくことになる。
モデル↔DBテーブル名に対応
DBのテーブル名「articles」の場合、モデルは以下のプログラムが対応して作成される。
/Model/Entity/Article.php
/Model/Table/ArticleTable.php
URL→コントローラー名(+メソッド)、ビュー名に対応
http://◯◯◯/articles/
/src/Controller/ArticlesController.php
index() 内を実行
http://◯◯◯/articles/add/
/src/Controller/ArticlesController.php
add() 内を実行
URLとコントローラーの関係は自動的に命名規則で決定しますが、変更したい場合は、/config/routes.php を変更することでルーティングを変更できます。