CakePHP3をいじってみる

前回はインストールを行ってみました。
今回はちょっとプログラムのほうもいじってみてどの程度変わったか見てみます。

composerからのインストールであればたぶんパーミッションはそのままでOKだと思います。
データベースの設定は./config/app.php の中で行うように変更になったようです。(以前のcore.php+database.php+mail.phpが合体した感じ?)
設定内容は中を見れば大体検討が付くかと思います。
これでWelcomeページを再表示させると、データベース欄がOKの表示になるはずです。

次にbakeで各モジュールのファイルを作ってみたいと思います。
起動方法が変更になってモデルを作る場合は

bin/cake bake model テーブル名

といった感じで、すべてパラメータで指定するようになっています。
というわけで、db上にこんな感じで適当にusersテーブルを作って

CREATE TABLE `users` (
  `id` int(11) NOT NULL,
  `email` varchar(521) NOT NULL,
  `password` varchar(64) NOT NULL,
  `modified` datetime NOT NULL,
  `created` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `user_profiles` (
  `id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `contents` text,
  `modefied` datetime NOT NULL,
  `created` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

php bin/cake.php bake controller Users
php bin/cake.php bake model Users
php bin/cake.php bake template Users

ちなみに、下記のようにallを指定して一括で作成することもできるようです。
php bin/cake.php bake all users
php bin/cake.php bake all user_profiles

これで
http://localhost/users/
にアクセスすると、自動でアプリが生成されていることがわかります。

ちなみに、以前のバージョンは対話式でいろいろカスタマイズできましたが、できなくなっているようです。
これは大きなマイナス点ですね。

ファイルについては以前はapp(プロジェクト名)フォルダの下にありましたが
./src 以下の場所に移動になったようですが、それ以外はフォルダ構成は大体同じかと思います。
以前はappフォルダの中に、ユーザーがコーディングするものと、それ以外のcakeフレームワークで必要なファイルやPluginなどの外部ライブラリが混在していましたが、Cake3では基本的にユーザーがいじるプログラムソースファイルはsrcフォルダの中だけになりました。

ちょっと各ファイルの中身を見てみましょう。
まずはコントローラーから
UsersController.php
一覧表示のindexメソッド

    public function index()
    {
        $users = $this->paginate($this->Users);

        $this->set(compact('users'));
        $this->set('_serialize', ['users']);
    }

大体前と同じですが、pagenate()メソッドの引数が意味不明ですねこれ。
cookbookを見ると、なんと・・・
検索結果でもテーブルオブジェクトでもテーブル名でもよいらしいです。
うーん・・・わかりに安いようなわかりにくいような微妙な感じ。
set()メソッドの使い方は同じですが、_serializeを入れているのは何だろ?コントローラー名を入れているのか?
テンプレートでは使っていないっぽいのだが、すべてのアクションに入っているのが謎。
ざっと調べてみたけども情報が見つかりませんでした。

次にView

    public function view($id = null)
    {
        $user = $this->Users->get($id, [
            'contain' => []
        ]);

        $this->set('user', $user);
        $this->set('_serialize', ['user']);
    }

$this->Users->get()はModel:read()メソッドに相当するものですかね?
ちなみにrecursiveはなくなってcontainでモデル名を指定するようになったようです。
うーん。recursiveはそれはそれでコード量が少なくなる利点があってよかったと思うのですが…。

次はadd

    public function add()
    {
        $user = $this->Users->newEntity();
        if ($this->request->is('post')) {
            $user = $this->Users->patchEntity($user, $this->request->data);
            if ($this->Users->save($user)) {
                $this->Flash->success(__('The user has been saved.'));
                return $this->redirect(['action' => 'index']);
            } else {
                $this->Flash->error(__('The user could not be saved. Please, try again.'));
            }
        }
        $this->set(compact('user'));
        $this->set('_serialize', ['user']);
    }

変わったのはnewEntity()とpatchEntity()メソッドですね。
公式サイトの説明も読んだのですが、いまいち内容が理解できませんでした。
古いCakeのModel::create()とModel::set()メソッドに相当するものと理解しておけばよさそうです。

    public function edit($id = null)
    {
        $user = $this->Users->get($id, [
            'contain' => []
        ]);
        if ($this->request->is(['patch', 'post', 'put'])) {
            $user = $this->Users->patchEntity($user, $this->request->data);
            if ($this->Users->save($user)) {
                $this->Flash->success(__('The user has been saved.'));
                return $this->redirect(['action' => 'index']);
            } else {
                $this->Flash->error(__('The user could not be saved. Please, try again.'));
            }
        }
        $this->set(compact('user'));
        $this->set('_serialize', ['user']);
    }

editもaddとあまり変わりません。
ちなみに、Modelのメソッドで返されるのはデータの配列でしたが、Cake3からはデータのオブジェクトになっているようです。
どちらかというと、配列で返してもらったほうが操作がしやすいと思うのですが、取得したデータに対して再度検索をかけたりも
できるらしいので(サブクエリができるようになった?)いろいろメリットもあるようです。

    public function delete($id = null)
    {
        $this->request->allowMethod(['post', 'delete']);
        $user = $this->Users->get($id);
        if ($this->Users->delete($user)) {
            $this->Flash->success(__('The user has been deleted.'));
        } else {
            $this->Flash->error(__('The user could not be deleted. Please, try again.'));
        }
        return $this->redirect(['action' => 'index']);
    }

deleteに関してもほぼ同じ。
editと同様に処理してdeleteメソッドで削除ができます。

細かいところは見ていませんが、根本的なところがだいぶ変わっているようです。
正直、古いCakeの知識は全く役にたたないようです。
ですのでCake1->Cake2の学習コストよりも習得にかなりのコストがかかるように思います。

bakeなど便利だった機能も必要最低限の部分しか実装されていないのでかなり手書きでの調整が必要です。

新しいだけプラグインなどのも未整備なので、アプリ作成のコストもやはり高くなってしまいそうです。
急ぎのプロジェクトなどの場合にはまだ使うのは早計かもしれません。

正直に言って、このこれらの変更は改悪だと思います。
ここまで変更するのであれば、CakePHPではなく、別の名前のプロジェクトとすべきだと思います。
なぜなら、何かわからないことがあって調べようとしても、旧版の全く関係ない情報ばかりヒットしてしまいます。
仕様がかなり近い1系と2系でもかなり混乱が生じましたが、CakePHP3の登場でさらに混乱に拍車がかかっていると思います。
以前のバージョンもそうですが、公式のリファレンスもかなりひどいつくりで、引数の説明がほとんどありません。
ソースの各メソッドの説明文でかろうじて引数はわかるのですが、連想配列で渡されるものが多いので結局何を渡してい
いのかわかりません。

情報が少ないのが一番の懸念点ですね。
CakePHP3を開設した日本語の書籍もまだないので、自由に使いこなせるようになるのはだいぶ困難が伴いそうです。

タイトルとURLをコピーしました