cakephp3 クイックスタートを実行してみる

#cakephp3のクイックスタートをやってみた

参考URL：https://book.cakephp.org/3/ja/quickstart.html

指示通りにcakeのプロジェクトをインストールする。

作業ディレクトリが出来たらDBを作成する。
phpmyadminとMAMPで環境構築した。
sqlのところにクイックスタートのsql文を入れる。

sql

```sql
    id INT AUTO_INCREMENT PRIMARY KEY,
    email VARCHAR(255) NOT NULL,
    password VARCHAR(255) NOT NULL,
    created DATETIME,
    modified DATETIME
);

CREATE TABLE articles (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    title VARCHAR(255) NOT NULL,
    slug VARCHAR(191) NOT NULL,
    body TEXT,
    published BOOLEAN DEFAULT FALSE,
    created DATETIME,
    modified DATETIME,
    UNIQUE KEY (slug),
    FOREIGN KEY user_key (user_id) REFERENCES users(id)
) CHARSET=utf8mb4;

CREATE TABLE tags (
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(191),
    created DATETIME,
    modified DATETIME,
    UNIQUE KEY (title)
) CHARSET=utf8mb4;

CREATE TABLE articles_tags (
    article_id INT NOT NULL,
    tag_id INT NOT NULL,
    PRIMARY KEY (article_id, tag_id),
    FOREIGN KEY tag_key(tag_id) REFERENCES tags(id),
    FOREIGN KEY article_key(article_id) REFERENCES articles(id)
);

INSERT INTO users (email, password, created, modified)
VALUES
('cakephp@example.com', 'secret', NOW(), NOW());

INSERT INTO articles (user_id, title, slug, body, published, created, modified)
VALUES
(1, 'First Post', 'first-post', 'This is the first post.', 1, now(), now());
```


##DB接続について

![スクリーンショット 2021-01-27 10.52.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/10b317ce-9ef0-0cac-7f25-05826458cc71.png)
config/app_local.phpとconfig/app.phpにDBの記述を記入

＊ローカル環境ではapp_local.phpに記述しないとDBが接続されない*

app.php

```php

    'Datasources' => [
        'default' => [
            'className' => 'Cake\Database\Connection',
            'driver' => 'Cake\Database\Driver\Mysql',
            'persistent' => false,
            'host' => 'localhost',
            'username' => 'root',
            'password' => 'root',
            'database' => 'cms_test',
            'encoding' => 'utf8mb4',
            'timezone' => 'UTC',
            'cacheMetadata' => true,
        ],
    ],
```


app_local.php

```php

    'Datasources' => [
        'default' => [
            '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' => 'root',
            'database' => 'cms_test',
            'log' => true,
            'url' => env('DATABASE_URL', null),
        ],
    ],
```

これで接続ができるようになる。


##Modelを作っていく

モデルは、CakePHP アプリケーションの心臓部です。データを読んだり変更する
Table オブジェクトは、指定されたテーブルの中に保存されたエンティティーの集合へのアクセスを提供
CakePHP のモデルは Table と Entity オブジェクトで構成

###今回主に使用するDBのTableはarticlesテーブル
その為Tableに作成するファイルは**「Table/ArticlesTable.php」**と**「Entity/Articles.php」**


Table/ArticlesTable.php

```php
<?php
// src/Model/Entity/Article.php
//エンティティーは、 データベースの１つのレコードを表し、データに対して行レベルの振る舞いを提供

namespace App\Model\Entity;

use Cake\ORM\Entity;

class Article extends Entity
{
    protected $_accessible = [
        '*' => true,
        'id' => false,
        'slug' => false,
    ];
}
```

Entity/Articles.php

```php
<?php
// src/Model/Table/ArticlesTable.php
//Table オブジェクトを ArticlesTable と名付けることで、CakePHP は、命名規則により articles テーブルを使用するモデルであると解釈
namespace App\Model\Table;

use Cake\ORM\Table;

class ArticlesTable extends Table
{
    public function initialize(array $config)
    {
        // created や modified カラムを自動的に更新する Timestamp ビヘイビアー
        $this->addBehavior('Timestamp');
    }
}
```


##コントローラーの作成

**src/Controller/ArticlesController.php**を作成する。

コントローラーの基本の外観は以下でこのclassの中にfunctionを記述していく。
そしてそのfunctionの名前がURLになる。
**www.example.com/articles/index (www.example.com/articles と同じ) をリクエストした場合、CakePHP は、 ArticlesController の index メソッドを呼ぶ。**

外観

```php
<?php
// src/Controller/ArticlesController.php

namespace App\Controller;

class ArticlesController extends AppController
{
//この中にfunctionnを書いていく
}
```

indexファンクション記入後

```php
<?php
// src/Controller/ArticlesController.php

namespace App\Controller;

class ArticlesController extends AppController
{
    public function index()
    {
        $this->loadComponent('Paginator');
        $articles = $this->Paginator->paginate($this->Articles->find());
        $this->set(compact('articles'));
    }
}
```
このコントローラーは、命名規則によって自動的にロードされる Articles モデルを使用して、 データベースからページ分けされた記事を取得します。


##テンプレート（ビュー）の作成
モデルからデータを取得し、ビューのコンテキストを準備するコントローラーを上記で作成したので indexアクションのビューテンプレートを作成します。

**CakePHP のテンプレートファイルは、 src/Template の中で 対応するコントローラーの名前をつけたフォルダーの中に保存されます。 今回の場合、 'Articles' という名前のフォルダーを作成する必要があります。**

src/Template/Articles/index.ctp

```php
<!-- File: src/Template/Articles/index.ctp -->

<h1>記事一覧</h1>
<table>
    <tr>
        <th>タイトル</th>
        <th>作成日時</th>
    </tr>

    <!-- ここで、$articles クエリーオブジェクトを繰り返して、記事の情報を出力します -->

    <?php foreach ($articles as $article): ?>
    <tr>
        <td>
            <?= $this->Html->link($article->title, ['action' => 'view', $article->slug]) ?>
        </td>
        <td>
            <?= $article->created->format(DATE_RFC850) ?>
        </td>
    </tr>
    <?php endforeach; ?>
</table>
```

$this->Html というオブジェクト これは、CakePHP の HtmlHelper のインスタンスです。
ここで**ヘルパー**が使用されていることを覚えておく。
link() メソッドは、 与えられたリンクテキスト(第１パラメーター) と URL (第２パラメーター) を元に HTML リンクを生成する。


####この時点で、ブラウザーで localhost/プロジェクト名/articles/index を 見ることができる

![スクリーンショット 2021-01-27 11.47.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/a3aaba26-8b58-fa52-046e-ce2f9f8a3c17.png)

#ここまでのまとめ
###使用しているDBのtable：article

####モデル
**テーブル**
**src/Model/Table/ArticlesTable.phpを作成**
→読取り時にタイムスタンプを設定し時刻を取得

**エンティティ**
**src/Model/Entity/Article.phpを作成**
→ 一括代入 (Mass Assignment) によって どのようにプロパティーを変更できるかを制御するプロパティー _accessible をセットアップ

###コントローラー
**src/Controller/ArticlesController.phpを作成**
→命名規則によって自動的にロードされる Articles モデルを使用して、 データベースからページ分けされた記事を取得。次にテンプレートの中に記事を渡すために set()を使用。CakePHP は、 コントローラーのアクションが完了した後、自動的にテンプレートを描画する。


###ビュー
**src/Template/Articles/index.ctpを作成**
→コントローラー側で設定したset()を受け取り'articles' 変数を割り当てることが出来るようになった。こちらを使用し表示するデータをコードで記述する。またlink()メソッドでリンクを作成することも可能にしている。
ここまででコントローラーに指定したアクション（function）名でURLを叩くと描画される。

####この後は表示したindexページから編集、更新、削除が出来るように今回作成した各ファイルに追記していく形になります。


#補足：その他メソッドについてなど

####initialize（）はCakePHPバージョン> 3.0で導入
initialize（）は、コンストラクターが呼び出された後に常に呼び出されます。ただし、特定のコントローラーでアクションメソッドが見つからない場合、beforeFilter（）は呼び出されません。
initialize（）メソッドは通常、新しいコンポーネントやヘルパーの追加などを初期化するために使用されます。ただし、beforeFilter（）では、通常、グローバルロジック部分の実行に使用される。
[参考リンク](https://riptutorial.com/cakephp/example/14794/what-is-initilaize---method-#:~:text=initialize%EF%BC%88%EF%BC%89%E3%81%AFCakePHP%E3%81%AE%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3,%E5%90%8C%E3%81%98%E3%82%88%E3%81%86%E3%81%AB%E8%A6%8B%E3%81%88%E3%81%BE%E3%81%99%E3%80%82&text=initialize%EF%BC%88%EF%BC%89%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%AF%E3%80%81%E6%96%B0%E3%81%97%E3%81%84,%E7%9A%84%E3%81%AB%E4%BD%BF%E7%94%A8%E3%81%95%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82)	

![スクリーンショット 2021-01-27 11.47.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/87f92558-cffc-9a07-514e-6438bf3e07de.png)