新しくなったCakePHP5.xを XAMPPで構築してみる

PHP
この記事は約11分で読めます。

この記事は、1年前に書かれました。

はじめに

CakePHP5がリリースされていたことを知りませんでした。
普段、オレオレフレームワーク(独自)ばかり使用しており、あまりLaravelやらCakeは使用しないのですが、CakePHPをがっつり使用したのはバージョン2か3の頃だったかと記憶しています。
いつの間にやらComposerでインストールできるようになったCakeですが、最近はLaravelばかりさわっていたので、CakePHP5がリリースされた機会に遊んでみることにしました。

CakePHP5のシステム要件

公式サイトから抜粋したシステム要件です。

  • HTTP サーバー。例: Apache。mod_rewrite が推奨されますが、必須ではありません。
  • PHP 8.1 以上 (PHP 8.2 も含む)
  • mbstring PHP エクステンション
  • intl PHP エクステンション
  • simplexml PHP エクステンション
  • PDO PHP エクステンション
インストール - 5.x

XAMPPのバージョン確認

ちょうど、PHP 8.1.6のXAMPPが入っていたため、この環境を使用します。
以下のディレクトリに直下にプロジェクト名cmsでインストールすることにします。

d:/xampp/htdocs/cake/

composerでインストール。念のためバージョン指定しておきます。

composer create-project --prefer-dist cakephp/app:5.0.0 cms 

いきなりエラーで怒られました。
半自動インストールのフレームワークなどは、こういったエラーが出るとやる気がそがれます。
これ、かなり以前にCakePHP4リリース時にも見覚えのあるエラーです。php.iniをゴニョゴニョした記憶があります。

php.iniを開き、intlで検索してみたところ、ありましたありました。
セミコロンでコメントアウトされているので、コメントを外します。

;extension=ffi
;extension=ftp
extension=fileinfo
;extension=gd
;extension=gettext
;extension=gmp
;extension=intl
;extension=imap
extension=mbstring
;extension=exif      ; Must be after mbstring as it depends on it
;extension=mysqli
;extension=oci8_12c  ; Use with Oracle Database 12c Instant Client
;extension=oci8_19  ; Use with Oracle Database 19 Instant Client
;extension=odbc

中途半端に作成されたディレクトリ/cake/cmsを一旦削除して、再度composerにてインストール。
今度は問題なく進みました。続いてパーミッションの質問が聞かれるのでひとまずYで。
これでCakePHPのインストールは完了です。

次にローカル内で疑似ドメインにてアクセスできるように設定します。
今回はcakeblog.localhost.jpでアクセスできるようにします。
xamppフォルダ/apache/conf/extra/httpd-vhosts.confのファイルを開いて、バーチャルホストの設定をおこないます。これ、xamppのhtdocs直下にプロジェクトを作成した場合は別におこなわなくても構いません。

<VirtualHost *:80>
    ##ServerAdmin webmaster@dummy-host2.example.com
    DocumentRoot "D:/xampp816/htdocs/cake/cms"
    ServerName cakeblog.localhost.jp
    ErrorLog "logs/dainichi.localhost.jp-error.log"
    ##CustomLog "logs/dummy-host2.example.com-access.log" common
</VirtualHost>

hostsファイルも設定しておきましょう。

127.0.0.1 cakeblog.localhost.jp

XAMPPコントロールパネルにてApacheとMySQLを起動します。

早速cakeblog.localhost.jpでアクセスしてみます。
エラー??PHPバージョン8.2.0以上??
公式ではPHP8.1以上って書いてあったのですが・・。さらにやる気をそがれますね。

気を取り直してXAMPPでPHP8.2.x環境を用意します。
MySQLのrootパスワードなどもサクサクっと設定し、環境を準備できたら再度composerでインストールします。バーチャルホストの設定も再度おこないます。
再び、cakeblog.localhost.jpにてアクセスして、出ましたWelcomeページ。

ちなみに、以下のコマンドでも開発用のサーバーが起動します。

bin/cake server

起動後以下のURLへアクセスすると、同じ画面が表示されます。

http://localhost:8765/

せかっくなので公式のチュートリアルをやってみます。

CMS チュートリアル - データベース作成 - 5.x

データベースを作成します。

公式のテーブル作成SQL文をそのまま使用してテーブルを作成します。

ユーザーも作成しておきます。パスワードも適当に設定します。ひとまずフルフル権限で。

CakePHPからデータベースへの接続設定をおこないます。こちらもチュートリアルどおり。
なのですが、チュートリアルではconfig/app.phpを修正しろと書かれていますが、app_local.phpがあるとそちらで上書きされます。ということでapp_local.phpを編集します。

    'Datasources' => [
        'default' => [
            'host' => 'localhost',
            //'port' => 'non_standard_port_number',
            'username' => 'cake_cms',
            'password' => 'パスワード',
            'database' => 'cake_cms',
            /*
             * If not using the default 'public' schema with the PostgreSQL driver
             * set it here.
             */
            //'schema' => 'myapp',

            /*
             * You can use a DSN string to set the entire configuration
             */
            'url' => env('DATABASE_URL', null),
        ],

再度ブラウザからアクセスして以下のように、帽子が緑色のアイコンになればCakeからのDB接続は完了です。

最初のモデルの作成

チュートリアルどおりにサクサクとやってみましょう。

CMS チュートリアル - データベース作成 - 5.x

src/Model/Table/ArticlesTable.phpのファイルを作成します。ここで注意です。
チュートリアルのソースコードにバグがあります。parent::initialiazeの行の末尾にセミコロンが抜けていますのでエラーとなります。PHP初心者の方はここで焦るかもしれません。何せチュートリアルが間違っているのですから。

<?php
// src/Model/Table/ArticlesTable.php
declare(strict_types=1);

namespace App\Model\Table;

use Cake\ORM\Table;

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

src/Model/Entity/Article.phpを作成します。

<?php
// src/Model/Entity/Article.php
namespace App\Model\Entity;

use Cake\ORM\Entity;

class Article extends Entity
{
    protected array $_accessible = [
        'title' => true,
        'body' => true,
        'published' => true,
        'created' => true,
        'modified' => true,
        'users' => true,
    ];
}

コントローラーの作成

src/Controller/ArticlesController.phpを作成します。

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

namespace App\Controller;

class ArticlesController extends AppController
{
    public function index()
    {
        $articles = $this->paginate($this->Articles);
        $this->set(compact('articles'));
    }
}

テンプレートの作成

templates/Articles/index.phpを作成します。ディレクトリが無い場合は作成しましょう。

<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>

http://cakeblog.localhost.jp/articles/index へアクセスしてみます。
以下のように表示されました。

引き続き試したい方は、チュートリアルに沿って進めてみてください。

最後に

普段、クライアントの意向でPHPではフルスクラッチの案件が多いのですが、フレームワークのメジャーバージョンが変わる時には一応触れておくようにしています。
CakePHPもLaravelも便利なフレームワークですが、どちらかと言えばLaravelのほうが柔軟性があるような気がします。CakePHPは「設定より規約」なのでファイル名など結構ガチガチなルールで、そのあたりの学習コストはCakeのほうが掛かりそうです。ただ、その分ディレクトリ構造はCakeのほうがシンプルな気がします。
LaravelはCakeより自由度が高い印象です。認証もLavelBreezeを使用するとかなり簡単に高度な認証システムが出来あがりますね。
Viteを導入したり、Reactとの連携などトレンドを敏感に取り入れるところもLaravel人気の要因かもしれません。

以上、CakePHP+Xampp環境の構築の参考になれば。