よしかわーるど

プログラミングで世界を変える

2018-05-16

CakePHPを学ぶ 1日目

参考文献

https://book.cakephp.org/3.0/ja/tutorials-and-examples/blog/blog.html

対象読者

ぼく、CakePHP3 を初めて触る方

実行環境

MacBookPro 2015 Early MySQL5.7.21 composer version 1.6.3 cakephp/app (3.5.1)

composer self-update && composer create-project –prefer-dist cakephp/app blog

データベースの作成

CakePHP の命名規則を参考にデータベースの作成をします。

CREATE TABLE articles (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(50),
    body TEXT,
    created DATETIME DEFAULT NULL,
    modified DATETIME DEFAULT NULL
);

/* それから、テスト用に記事をいくつか入れておきます: */
INSERT INTO articles (title,body,created)
    VALUES ('タイトル', 'これは、記事の本文です。', NOW());
INSERT INTO articles (title,body,created)
    VALUES ('またタイトル', 'そこに本文が続きます。', NOW());
INSERT INTO articles (title,body,created)
    VALUES ('タイトルの逆襲', 'こりゃ本当にわくわくする!うそ。', NOW());

config/app.phpファイルの中の Datasources.default 配列の変更 username, password, database は自分のデータベースによって異なります。

'Datasources' => [
        'default' => [
            'className' => 'Cake\Database\Connection',
            'driver' => 'Cake\Database\Driver\Mysql',
            'persistent' => false,
            'host' => 'localhost',

            //'port' => 'non_standard_port_number',
            'username' => 'root',
            'password' => '',
            'database' => 'cake_blog',
            'encoding' => 'utf8',
            'timezone' => 'UTC',
            'flags' => [],
            'cacheMetadata' => true,
            'log' => false,

            'quoteIdentifiers' => false,

            //'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'],

            'url' => env('DATABASE_URL', null),
        ],

追加の設定

セキュリティハッシュ用のカスタム文字列を設定出来ます。なぜ、salt が必要なのかは安全なパスワードハッシュを読んで下さい。

    'Security' => [
        'salt' => env('SECURITY_SALT', 'something long and containing lots of different values.'),
    ],

モデルの作成

CakePHP のモデルクラスのファイルは、TableオブジェクトEntityオブジェクトに分離して存在します。 src/Model/Tableのディレクトリ内をチェック。src/Model/Table/ArticlesTable.phpを作成。

<?php
namespace App\Model\Table;

use Cake\ORM\Table;
use Cake\Validation\Validator;

class ArticlesTable extends Table
{
    public function initialize(array $config)
    {
        $this->addBehavior('Timestamp');
    }

    public function validationDefault(Validator $validator)
    {
        $validator
            ->notEmpty('title')
            ->requirePresence('title')
            ->notEmpty('body')
            ->requirePresence('body');

        return $validator;
    }
}

コントローラーの作成

ArticlesController.phpを、src/Controllerディレクトリ内に配置。

<?php
namespace App\Controller;

use App\Controller\AppController;

class ArticlesController extends AppController
{

    public function initialize()
    {
        parent::initialize();

        $this->loadComponent('Flash'); // Include the FlashComponent
    }

    public function index()
    {
        $this->set('articles', $this->Articles->find('all'));
    }

    public function view($id)
    {
        $article = $this->Articles->get($id);
        $this->set(compact('article'));
    }

    public function add()
    {
        $article = $this->Articles->newEntity();
        if ($this->request->is('post')) {
            // 3.4.0 より前は $this->request->data() が使われました。
            $article = $this->Articles->patchEntity($article, $this->request->getData());
            if ($this->Articles->save($article)) {
                $this->Flash->success(__('Your article has been saved.'));
                return $this->redirect(['action' => 'index']);
            }
            $this->Flash->error(__('Unable to add your article.'));
        }
        $this->set('article', $article);
    }

    public function edit($id = null)
    {
        $article = $this->Articles->get($id);
        if ($this->request->is(['post', 'put'])) {
            // 3.4.0 より前は $this->request->data() が使われました。
            $this->Articles->patchEntity($article, $this->request->getData());
            if ($this->Articles->save($article)) {
                $this->Flash->success(__('Your article has been updated.'));
                return $this->redirect(['action' => 'index']);
            }
            $this->Flash->error(__('Unable to update your article.'));
        }

        $this->set('article', $article);
    }
    public function delete($id)
    {
        $this->request->allowMethod(['post', 'delete']);

        $article = $this->Articles->get($id);
        if ($this->Articles->delete($article)) {
            $this->Flash->success(__('The article with id: {0} has been deleted.', h($id)));
            return $this->redirect(['action' => 'index']);
        }
    }
}

ビューの作成

CakePHP のビューファイルは、src/Templateの中の、コントローラー名に対応するフォルダーの中に保存されています (この場合は、「Articles」というフォルダを作成します)。

index.ctp を作成します。http://localhost:8765/articles/index で見ることが出来ます。

<h1>Blog articles</h1>
<p><?= $this->Html->link('Add Article', ['action' => 'add']) ?></p>
<table>
    <tr>
        <th>Id</th>
        <th>Title</th>
        <th>Created</th>
        <th>Actions</th>
    </tr>

    <?php foreach ($articles as $article): ?>
    <tr>
        <td><?= $article->id ?></td>
        <td>
            <?= $this->Html->link($article->title, ['action' => 'view', $article->id]) ?>
        </td>
        <td>
            <?= $article->created->format(DATE_RFC850) ?>
        </td>
        <td>
            <?= $this->Form->postLink(
                'Delete',
                ['action' => 'delete', $article->id],
                ['confirm' => 'Are you sure?'])
            ?>
            <?= $this->Html->link('Edit', ['action' => 'edit', $article->id]) ?>
        </td>
    </tr>
    <?php endforeach; ?>

</table>

view.ctp を作成します。articles/viewの部分が view.ctp になります。

<h1><?= h($article->title) ?></h1>
<p><?= h($article->body) ?></p>
<p><small>Created: <?= $article->created->format(DATE_RFC850) ?></small></p>

add.ctp を作成します。articles/addの部分が add.ctp になります。

<h1>Add Article</h1>
<?php
    echo $this->Form->create($article);
    echo $this->Form->control('title');
    echo $this->Form->control('body', ['rows' => '3']);
    echo $this->Form->button(__('Save Article'));
    echo $this->Form->end();
?>

edit.ctp を作成します。articles/editの部分が edit.ctp になります。

<h1>Edit Article</h1>
<?php
    echo $this->Form->create($article);
    echo $this->Form->control('title');
    echo $this->Form->control('body', ['rows' => '3']);
    echo $this->Form->button(__('Save Article'));
    echo $this->Form->end();
?>

さいごに

もっと簡単な方法がありまして、bin/cake bake all articlesで自動的に作成してくれます。便利ですね。 以上で今回は終わります。

次回の記事

https://yoshikawataiki.net/posts/cake2/