cakephpを簡単に触ってみる

### はじめに
仕事でcakephpを使うことになりましたので、実際にcakephpを使ってみたいと思います！

### cakephpとは
phpで開発されたフレームワーク。MVCアーキテクチャを採用していてRuby on Railsの影響を受けてる。MVCの流れを簡単に確認しましたので備忘録も兼ねてまとめます。

### cakephpをインストール
とりあえず下記のコマンドでcakephpをインストール
composer create-project --prefer-dist cakephp/app:4 BlogApp

ディレクトリ構成はこんな感じです

BlogApp  
|-.github  
|-bin  
|-config  
|-database  
|-logs  
|-plugins  
|-resources  
|-src  
|-templates  
|-tests  
|-temp  
|-vendor  
|-webroot  
|-.editorconfig  
|-gitattributes  
|-.ignore  
|-.htaccess  
|-composer.json  
|-composer.lock  
|-index.php  
|-phpcs.xml  
|-phpstan.neon  
|-phpunit.xml.dist  
|-README.md  

### とりあえず何か表示してみる  

webroot配下にtest.htmlを作成します  
![スクリーンショット 2023-12-27 8.17.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634151/9f3d610b-fb4d-13de-fddd-001c5c40be43.png)

test.htmlは「テスト表示です」と表示させるだけにします。

![スクリーンショット 2023-12-28 23.38.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634151/1ad6cb0c-c755-c533-f29b-5778597fb5a2.png)


cakephpではwebroot配下がドキュメントルートで、cssとか読み込ませておきたいファイルを作成します。  
ドキュメントルートに置いたファイルはルートバスからアクセスできます。  
![スクリーンショット 2023-12-27 8.15.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634151/32aff2fc-df0d-4973-9ed8-9ca91d77a9d0.png)


### コントローラーを作成
下記コマンドでコントローラーを作成します。  
Laravelのartisanみたいにcakeではbakeを使うみたいです。  
cakeでbakeは覚えやすいですね  
```
bin/cake bake controller tests
```

凄い。  
actionが一気にたくさん出来ました。
```
<?php
declare(strict_types=1);

namespace App\Controller;

/**
 * Tests Controller
 *
 * @method \App\Model\Entity\Test[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
 */
class TestsController extends AppController
{
    /**
     * Index method
     *
     * @return \Cake\Http\Response|null|void Renders view
     */
    public function index()
    {
        $tests = $this->paginate($this->Tests);

        $this->set(compact('tests'));
    }

    /**
     * View method
     *
     * @param string|null $id Test id.
     * @return \Cake\Http\Response|null|void Renders view
     * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
     */
    public function view($id = null)
    {
        $test = $this->Tests->get($id, [
            'contain' => [],
        ]);

        $this->set(compact('test'));
    }

    /**
     * Add method
     *
     * @return \Cake\Http\Response|null|void Redirects on successful add, renders view otherwise.
     */
    public function add()
    {
        $test = $this->Tests->newEmptyEntity();
        if ($this->request->is('post')) {
            $test = $this->Tests->patchEntity($test, $this->request->getData());
            if ($this->Tests->save($test)) {
                $this->Flash->success(__('The test has been saved.'));

                return $this->redirect(['action' => 'index']);
            }
            $this->Flash->error(__('The test could not be saved. Please, try again.'));
        }
        $this->set(compact('test'));
    }

    /**
     * Edit method
     *
     * @param string|null $id Test id.
     * @return \Cake\Http\Response|null|void Redirects on successful edit, renders view otherwise.
     * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
     */
    public function edit($id = null)
    {
        $test = $this->Tests->get($id, [
            'contain' => [],
        ]);
        if ($this->request->is(['patch', 'post', 'put'])) {
            $test = $this->Tests->patchEntity($test, $this->request->getData());
            if ($this->Tests->save($test)) {
                $this->Flash->success(__('The test has been saved.'));

                return $this->redirect(['action' => 'index']);
            }
            $this->Flash->error(__('The test could not be saved. Please, try again.'));
        }
        $this->set(compact('test'));
    }

    /**
     * Delete method
     *
     * @param string|null $id Test id.
     * @return \Cake\Http\Response|null|void Redirects to index.
     * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
     */
    public function delete($id = null)
    {
        $this->request->allowMethod(['post', 'delete']);
        $test = $this->Tests->get($id);
        if ($this->Tests->delete($test)) {
            $this->Flash->success(__('The test has been deleted.'));
        } else {
            $this->Flash->error(__('The test could not be deleted. Please, try again.'));
        }

        return $this->redirect(['action' => 'index']);
    }
}
```
### templateの内容を表示する

TestsControllerのindexメソッドを空にします。

```
    /**
     * Index method
     *
     * @return \Cake\Http\Response|null|void Renders view
     */
    public function index()
    {

    }
```
templatesにTestsフォルダを作成し、index.phpファイルを作成します。
![スクリーンショット 2023-12-27 9.27.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634151/fdaf55b3-4bbb-7311-9b5c-fddc8a306fb3.png)


index.phpファイルにはh１だけ記述します
```
<h1>テンプレートの表示確認です</h1>
```

/Testsにアクセスします。  

![スクリーンショット 2023-12-27 9.01.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634151/cb1e082b-2165-4937-3033-fe69e0419615.png)

![](<スクリーンショット 2023-12-27 9.01.21.png>)
cakephpでは、コントローラー名とアクション名を、templateのフォルダ名とファイル名を合わせる事によって、templateの自動読み込みをしてくれます。  
 index.phpファイルの内容が表示されました。  

![スクリーンショット 2023-12-27 9.03.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634151/dc7feb66-0242-b49a-1c9f-e3e027ec01d4.png)


### コントローラーの値をtemplateで表示する
通常のアプリケーションでは、コントローラーで処理した内容をtemplateで表示させると思いますので、実際に実装してみたいと思います。

TestsControllerにviewアクションを追加します。  
templateに値を渡すときはsetメソッドを使います
```
    public function view($id = null)
    {
        $this->set(['id' => $id]);
    }
```
Testフォルダ配下には、viewファイルを作成します。
![スクリーンショット 2023-12-27 9.27.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634151/9b058460-4b8b-9588-9bac-cf0a00dab84a.png)


 
viewファイルを下記のようにします

![スクリーンショット 2023-12-27 9.32.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634151/6449ef64-e910-f23b-ae6c-e012e9ed37d9.png)


Tests/view/300にアクセスすると、パラメーターの値が表示されました！
![スクリーンショット 2023-12-27 9.34.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634151/6a1205e3-ad59-fa40-1c53-49e12a7a31cd.png)


今回はset関数でtemplateに値を持っていきましたが、Laravelみたいにcompact関数などで持っていくことも可能です。


### データベースから情報を取得する

まずはマイグレーションファイルの作成
```
bin/cake bake migration CreatePosts
```

カラムの設定
```
class CreatePosts extends AbstractMigration
{
    /**
     * Change Method.
     *
     * More information on this method is available here:
     * https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method
     * @return void
     */
    public function change(): void
    {
        $table = $this->table('posts');
        $table
            ->addColumn('title', 'string', [
                'limit' => 150,
                'null' => false
            ])
            ->addColumn('description', 'text', [
                'limit' => 255
            ])
            ->addColumn('body', 'text')
            ->addColumn('published', 'boolean', [
                'default' => false
            ])
            ->addColumn('created', 'datetime')
            ->addColumn('modified', 'datetime')
            ->create();
    }
}
```
マイグレーションをしてテーブル作成
```
bin/cake migrations migrate
```
作成したテーブルにテストデータを入れるために、seedファイルを作成する
```
bin/cake bake seed Posts
```
seedファイルにダミーデータを記述する
```
    public function run(): void
    {
        $data = [
            [
                'title' => '最初の投稿',
                'description' => '最初の投稿の概要',
                'body' => '最初の投稿内容',
                'published' => 1,
                'created' => '2020-05-02 10:00:00',
                'modified' => '2020-05-02 10:00:00',
            ],
            [
                'title' => '2番目の投稿',
                'description' => '2番目の投稿の概要',
                'body' => '2番目の投稿内容',
                'published' => 1,
                'created' => '2020-05-02 10:00:00',
                'modified' => '2020-05-02 10:00:00',
            ],
        ];

        $table = $this->table('posts');
        $table->insert($data)->save();
    }
```
ダミーデータをテーブルに登録する為にコマンドを入力する。
```
bin/cake migrations seed
```
テーブルにダミーデータが登録されているか確認する。

![スクリーンショット 2023-12-28 0.03.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634151/e1e0d505-3aa0-b4f5-174c-d04e9c39c227.png)


モデルを作成する。

```
bin/cake bake model posts
```
![スクリーンショット 2023-12-28 0.21.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634151/0125fb82-acf1-fa63-ac5c-2f2522820805.png)


```
    /**
     * Index method
     *
     * @return \Cake\Http\Response|null|void Renders view
     */
    public function index()
    {
        $this->loadModel('Posts');
        $posts = $this->Posts->find('all');

        dd($posts->toArray());
    }
```

http://localhost:8765/tests/ にアクセスすると、Postsテーブルの情報が取得できています。

![スクリーンショット 2023-12-28 23.30.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634151/eb216154-01c6-4ad2-9937-56f5ca93c67e.png)

### さいごに
cakephpを簡単に触ってみました！MVCということもあり、laravelに似てますね。他にも便利なヘルパーなどがありますので、実装しながら学んでいきたいと思います！