著者は、Write for DOnationsプログラムの一部として寄付を受け取るためにFree and Open Source Fundを選択しました。
前書き
CakePHPは、人気があり機能が豊富なPHPWebフレームワークです。 データベースとの対話、SQLインジェクションに対する保護、ビューコードの生成など、Web開発の一般的な問題の多くを解決します。 これは、アプリケーションのさまざまな部分を分離するmodel-view-controller(MVC)パターンに準拠しており、開発者がアプリのさまざまな部分で並行して作業できるようにします。 また、組み込みのセキュリティと認証も提供します。 基本的なデータベースアプリを作成することはシームレスなプロセスであり、CakePHPのプロトタイプ作成に役立ちます。 ただし、CakePHPを使用して、展開用の完全に開発されたWebアプリケーションを作成することもできます。
このチュートリアルでは、サンプルのCakePHP Webアプリケーションを実稼働環境にデプロイします。 これを実現するには、サンプルデータベースとユーザーをセットアップし、Apacheを構成し、アプリをデータベースに接続し、デバッグモードをオフにします。 また、CakePHPのbake
コマンドを使用して、記事モデルを自動的に生成します。
前提条件
このチュートリアルを始める前に、次のものが必要です。
-
ルートアクセスとsudo、非ルートアカウントでUbuntu 18.04を実行しているサーバーでは、this initial server setup guideに従ってこれを設定できます。
-
How To Install Linux, Apache, MySQL, PHP (LAMP) stack on Ubuntu 18.04に従ってインストールされたLAMPスタック。 この記事の執筆時点では、PHP 7.2が最新バージョンです。
-
サーバーにインストールされているComposer(PHPパッケージマネージャー)。 これを行う方法のガイドについては、How To Install and Use Composer on Ubuntu 18.04にアクセスしてください。 そのチュートリアルの最初の2つのステップを完了するだけです。
-
Let's Encryptで保護されたApache。 この前提条件を完了するには、最初にHow To Install Apache on Ubuntu 18.04のステップ5に従って仮想ホストを設定する必要があります。 その後、How To Secure Apache with Let’s Encrypt on Ubuntu 18.04に従って、Let’sEncryptでApacheを保護できます。 要求されたら、必須のHTTPSリダイレクトを有効にします。
-
完全に登録されたドメイン名。 このチュートリアルでは、全体を通して
example.com
を使用します。 Namecheapでドメイン名を購入するか、Freenomで無料でドメイン名を取得するか、選択したドメインレジストラを使用できます。 -
次の両方のDNSレコードがサーバーに設定されています。 それらを追加する方法の詳細については、DigitalOcean DNSのthis introductionをたどることができます。
-
サーバーのパブリックIPアドレスを指す
example.com
を含むAレコード。 -
サーバーのパブリックIPアドレスを指す
www.example.com
を含むAレコード。
-
[[step-1 -—- installing-dependencies]] ==ステップ1—依存関係のインストール
アプリケーションの準備をするには、CakePHPが必要とするPHP拡張機能をインストールすることから始めます。
パッケージマネージャーキャッシュを更新することから始めます。
sudo apt update
CakePHPには、mbstring
、intl
、およびsimplexml
のPHP拡張機能が必要です。これにより、マルチバイト文字列、国際化、およびXML処理のサポートが追加されます。 Composerの前提条件チュートリアルの一部としてmbstring
をインストールしました。 1つのコマンドで残りのライブラリをインストールできます。
sudo apt install php7.2-intl php7.2-xml -y
上記のバージョン番号(7.2)は、PHPの新しいバージョンで変わることに注意してください。
CakePHPに必要な依存関係をインストールしました。 これで、実稼働用にMySQLデータベースを構成する準備が整いました。
[[step-2 -—- setting-up-a-mysql-database]] ==ステップ2—MySQLデータベースのセットアップ
次に、ブログの記事に関する情報を保存するMySQLデータベースを作成します。 また、アプリケーションがデータベースへのアクセスに使用するデータベースユーザーを作成します。 この制御の分離を実現するには、データベース権限を変更します。 その結果、悪意のある攻撃者は、データベース資格情報を使用してもシステム上で問題を引き起こすことができなくなります。これは、実稼働環境での重要なセキュリティ予防策です。
MySQLシェルを起動します。
sudo mysql -u root -p
要求されたら、最初のLAMPインストール中に設定したパスワードを入力します。
次に、データベースを作成します。
CREATE DATABASE cakephp_blog;
次のような出力が表示されます。
OutputQuery OK, 1 row affected (0.00 sec)
CakePHPアプリは、この新しいデータベースを使用して生産データを読み取り、保存します。
次に、MySQLに新しいcakephp_blog
データベースを操作するように指示します。
USE cakephp_blog;
次のような出力が表示されます。
OutputDatabase changed
次に、cakephp_blog
データベースにブログ記事のテーブルスキーマを作成します。 これを設定するには、次のコマンドを実行します。
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(50),
body TEXT,
created DATETIME DEFAULT NULL,
modified DATETIME DEFAULT NULL
);
ブログ記事を説明する5つのフィールドを持つスキーマを作成しました:
-
id
:記事の一意の識別子であり、主キーとして設定されます。 -
title
:記事のタイトルであり、最大50文字を含むテキストフィールドとして宣言されています。 -
body
:記事のテキストであり、TEXT
フィールドとして宣言されています。 -
created
:レコードが作成された日時です。 -
modified
:レコードが変更された日時です。
出力は次のようになります。
OutputQuery OK, 0 rows affected (0.01 sec)
cakephp_blog
データベースに記事を保存するためのテーブルを作成しました。 次に、次のコマンドを実行して、サンプル記事を入力します。
INSERT INTO articles (title, body, created)
VALUES ('Sample title', 'This is the article body.', NOW());
タイトルと本文のサンプルデータを含む記事の例を追加しました。
次の出力が表示されます。
OutputQuery OK, 0 rows affected (0.01 sec)
CakePHPアプリをデータベースに接続するには、新しいデータベースユーザーを作成し、その権限を制限する必要があります。
GRANT ALL PRIVILEGES ON cakephp_blog.* TO 'cake_user'@'localhost' IDENTIFIED BY 'password';
このコマンドは、データベース内のすべてのテーブルにすべての特権を付与します。
password
を選択した強力なパスワードに置き換えることを忘れないでください。
行った変更でデータベースを更新するには、次を実行してリロードします:
FLUSH PRIVILEGES;
新しいデータベースユーザーcake_user
を作成し、cakephp_blog
データベースでのみユーザー権限を付与したため、セキュリティが強化されました。
exit
と入力して、MySQLターミナルを終了します。
スキーマを使用して新しいデータベースを作成し、サンプルデータを入力して、適切なデータベースユーザーを作成しました。 次のステップでは、CakePHPアプリ自体をセットアップします。
[[step-3 -—- creating-the-blog-application]] ==ステップ3—ブログアプリケーションの作成
このセクションでは、Composerを使用してCakePHPアプリの例をインストールします。 Composerを使用すると、コマンドラインからCakePHPをインストールでき、特定のファイル許可と設定ファイルが自動的に設定されるため、有利です。
まず、Apache Webサーバーフォルダーに移動します。
cd /var/www/example.com/html
Apacheはこのディレクトリを使用して、外部から見えるファイルを保存します。 root
ユーザーがこのディレクトリを所有しているため、root以外のユーザーsammy
はこのディレクトリに何も書き込むことができません。 これを修正するには、次を実行してファイルシステムのアクセス許可を変更します。
sudo chown -R sammy .
Composerを使用して新しいCakePHPアプリを作成します。
composer create-project --prefer-dist cakephp/app cake-blog
ここでは、composer
を呼び出し、create-project
を使用して新しいプロジェクトを作成するように指示しました。 --prefer-dist cakephp/app
は、composer
にCakePHPをテンプレートとして使用し、cake-blog
を新しいアプリケーションの名前として使用するように指示します。
このコマンドが完了するまでに時間がかかる場合があることに注意してください。
Composerからフォルダーのアクセス許可を設定するように求められたら、y
で応答します。
このセクションでは、Composerを使用して新しいCakePHPプロジェクトを作成しました。 次のステップでは、Apacheが新しいアプリを指すように設定し、ブラウザで表示できるようにします。
[[step-4 -—- configuring-apache-to-point-to-your-app]] ==ステップ4—アプリを指すようにApacheを設定する
次に、新しいCakePHPアプリケーション用にApacheを構成し、CakePHPの要件である.htaccess
のオーバーライドを有効にします。 これには、Apache構成ファイルの編集が伴います。
実際のルーティングを行うには、.htaccess
ファイルを使用するようにApacheに指示する必要があります。 これらはアプリケーションのサブディレクトリ(必要な場合)にある構成ファイルで、Apacheはファイルを使用して、アプリケーションの要求された部分のグローバル構成を変更します。 他のタスクの中でも、これらにはURL書き換えルールが含まれますが、これは今調整します。
テキストエディタを使用してApacheグローバル設定ファイル(apache2.conf
)を開くことから始めます。
sudo nano /etc/apache2/apache2.conf
次のコードブロックを見つけます。
/etc/apache2/apache2.conf
...
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
...
次のように、AllowOverride
をNone
からAll
に変更します。
/etc/apache2/apache2.conf
...
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
...
ファイルを保存して閉じます。
次に、CakePHPインストールのwebroot
ディレクトリを指すようにApacheに指示します。 Apacheは、構成ファイルをUbuntu 18.04の/etc/apache2/sites-available
に保存します。 これらのファイルは、ApacheがWeb要求を処理する方法を管理します。
Let's Encrypt前提条件チュートリアルで、HTTPSリダイレクトを有効にしました。したがって、HTTPSトラフィックのみを許可します。 その結果、HTTPSトラフィックを構成するexample.com-le-ssl.conf
ファイルのみを編集します。
まず、example.com-le-ssl.conf
構成ファイルを開きます。
sudo nano /etc/apache2/sites-available/example.com-le-ssl.conf
変更する必要があるのは、DocumentRoot
を設定し、Apacheにコンテンツをブラウザに提供する場所を指示する1行だけです。 ファイルで次の行を見つけます。
/etc/apache2/sites-available/example.com-le-ssl.conf
DocumentRoot /var/www/example.com/html
次の強調表示されたコンテンツを追加して、CakePHPのインストールを指すようにこの行を編集します。
/etc/apache2/sites-available/example.com-le-ssl.conf
DocumentRoot /var/www/example.com/html/cake-blog/webroot
ファイルを保存し、エディターを終了します。
その後、Apacheを再起動して新しい構成を反映します。
sudo systemctl restart apache2
これで、ブラウザでhttps://your_domain/
にアクセスできます。
デフォルトのCakePHP成功ページが表示されます。 アプリケーションがデータベースに接続できないことを示すブロックがあることに気付くでしょう。 次のステップでは、アプリをデータベースに接続してこれを解決します。
これで、.htaccess
のオーバーライドが有効になり、Apacheが正しいwebroot
ディレクトリを指すようになりました。
[[ステップ-5 ---アプリをデータベースに接続する]] ==ステップ5—アプリをデータベースに接続する
このセクションでは、ブログが記事にアクセスできるように、データベースをアプリケーションに接続します。 CakePHPのデフォルトのconfig/app.php
ファイルを編集して、データベースへの接続を設定します。
アプリフォルダーに移動します。
cd /var/www/example.com/html/cake-blog
次のコマンドを実行して、config/app.php
ファイルを開きます。
sudo nano config/app.php
Datasources
ブロックを見つけます(次のようになります)。
/var/www/example.com/html/cake-blog/config/app.php
...
'Datasources' => [
'default' => [
'className' => 'Cake\Database\Connection',
'driver' => 'Cake\Database\Driver\Mysql',
'persistent' => false,
'host' => 'localhost',
...
//'port' => 'non_standard_port_number',
'username' => 'cake_user',
'password' => 'password',
'database' => 'cakephp_blog',
...
'username'
の場合、my_app
をデータベースユーザーのユーザー名に置き換え(このチュートリアルではcake_user
を使用)、secret
をデータベースユーザーのパスワードに置き換え、2番目のmy_app
をデータベース名(このチュートリアルではcakephp_blog
)。
ファイルを保存して閉じます。
ブラウザでアプリを更新し、Databaseセクションの下にある成功メッセージを確認します。 エラーが表示された場合は、前の手順に対して構成ファイルを再確認してください。
このステップでは、CakePHPアプリをMySQLデータベースに接続しました。 次のステップでは、記事とやり取りするためのユーザーインターフェースを構成するモデル、ビュー、コントローラーファイルを生成します。
[[step-6 -—- creating-the-article-user-interface]] ==ステップ6—Articleユーザーインターフェイスの作成
このセクションでは、CakePHPbake
コマンドを実行して、すぐに使用できる記事インターフェースを作成します。これにより、記事モデルが生成されます。 CakePHPでは、ベーキングにより、必要なすべてのモデル、ビュー、コントローラーが基本的な状態で生成され、さらなる開発の準備が整います。 すべてのデータベースアプリは、作成、読み取り、更新、削除(CRUD)操作を許可する必要があります。これにより、CakePHPのbake
機能は、これらの操作のコードを自動的に生成するのに役立ちます。 数分以内に、データの入力、保存、編集の準備ができたアプリの完全なプロトタイプを取得できます。
モデル、ビュー、およびコントローラーは、MVCパターンに関連しています。 その役割は次のとおりです。
-
モデルはデータ構造を表します。
-
ビューは、ユーザーフレンドリーな方法でデータを表示します。
-
コントローラーはユーザーの要求に応じて動作し、ビューとモデルの間の仲介者として機能します。
CakePHPは、CLI実行可能ファイルをbin/cake
の下に保存します。 主にベイク処理に使用されますが、さまざまなキャッシュをクリアするためのコマンドなど、他のコマンドを多数提供します。
bake
コマンドはデータベースをチェックし、見つかったテーブル定義に基づいてモデルを生成します。 次のコマンドを実行して開始します。
./bin/cake bake all
all
コマンドを渡すことにより、モデル、コントローラー、およびビューを一度に生成するようにCakePHPに指示します。
出力は次のようになります。
OutputBake All
---------------------------------------------------------------
Possible model names based on your database:
- articles
Run `cake bake all [name]` to generate skeleton files.
データベースからarticles
定義を適切に検出し、そのモデルのファイルを生成することを提案しています。
以下を実行して焼きます:
./bin/cake bake all articles
出力は次のようになります。
OutputBake All
---------------------------------------------------------------
One moment while associations are detected.
Baking table class for Articles...
Creating file /var/www/example.com/html/cake-blog/src/Model/Table/ArticlesTable.php
Wrote `/var/www/example.com/html/cake-blog/src/Model/Table/ArticlesTable.php`
Deleted `/var/www/example.com/html/cake-blog/src/Model/Table/empty`
Baking entity class for Article...
Creating file /var/www/example.com/html/cake-blog/src/Model/Entity/Article.php
Wrote `/var/www/example.com/html/cake-blog/src/Model/Entity/Article.php`
Deleted `/var/www/example.com/html/cake-blog/src/Model/Entity/empty`
Baking test fixture for Articles...
Creating file /var/www/example.com/html/cake-blog/tests/Fixture/ArticlesFixture.php
Wrote `/var/www/example.com/html/cake-blog/tests/Fixture/ArticlesFixture.php`
Deleted `/var/www/example.com/html/cake-blog/tests/Fixture/empty`
Bake is detecting possible fixtures...
Baking test case for App\Model\Table\ArticlesTable ...
Creating file /var/www/example.com/html/cake-blog/tests/TestCase/Model/Table/ArticlesTableTest.php
Wrote `/var/www/example.com/html/cake-blog/tests/TestCase/Model/Table/ArticlesTableTest.php`
Baking controller class for Articles...
Creating file /var/www/example.com/html/cake-blog/src/Controller/ArticlesController.php
Wrote `/var/www/example.com/html/cake-blog/src/Controller/ArticlesController.php`
Bake is detecting possible fixtures...
...
Baking `add` view template file...
Creating file /var/www/example.com/html/cake-blog/src/Template/Articles/add.ctp
Wrote `/var/www/example.com/html/cake-blog/src/Template/Articles/add.ctp`
Baking `edit` view template file...
Creating file /var/www/example.com/html/cake-blog/src/Template/Articles/edit.ctp
Wrote `/var/www/example.com/html/cake-blog/src/Template/Articles/edit.ctp`
Bake All complete.
出力では、CakePHPがarticles
データベースの機能的なボイラープレートを作成するために行ったすべての手順をログに記録していることがわかります。
次に、ブラウザで次の場所に移動します。
https://your_domain/articles
現在データベースにある記事のリストが表示されます。これには、Sample Titleというタイトルの1行が含まれています。 bake
コマンドは、記事の作成、削除、編集を可能にするこのインターフェイスを作成しました。 そのため、今後の開発の確実な出発点となります。 サイドバーのNew Articleリンクをクリックして、新しい記事を追加してみてください。
このセクションでは、CakePHPのbake
コマンドを使用して、モデル、ビュー、およびコントローラーファイルを生成しました。 記事を作成、削除、表示、編集できるようになりました。すべての変更はすぐにデータベースに保存されます。
次の手順では、デバッグモードを無効にします。
[[step-7 -—- disabling-debug-mode-in-cakephp]] ==ステップ7—CakePHPでデバッグモードを無効にする
このセクションでは、CakePHPのデバッグモードを無効にします。 デバッグモードではアプリが詳細なデバッグ情報を表示するため、これは重要です。これはセキュリティリスクです。 アプリケーションの開発が完了したら、この手順を完了します。
お気に入りのエディターを使用してconfig/app.php
ファイルを開きます。
sudo nano config/app.php
ファイルの先頭近くに、'debug'
モードの行があります。 ファイルを開くと、'debug'
モードがtrue
に設定されます。 次のように、これをfalse
に変更します。
config/app.php
...
'debug' => filter_var(env('DEBUG', false), FILTER_VALIDATE_BOOLEAN),
...
デバッグモードをオフにすると、src/Templates/Pages/home.ctp
の下にあるホームページにエラーが表示されます。
[.note]#Note:デフォルトルートを変更していないか、home.ctp
のコンテンツを置き換えていない場合、アプリのホームページにエラーが表示されるようになりました。 これは、デフォルトのホームページが開発中にステータスダッシュボードとして機能するが、デバッグモードが無効になっていると機能しないためです。
#
デバッグモードを無効にしました。 これから発生するエラーや例外は、スタックトレースとともにエンドユーザーに表示されないため、アプリケーションのセキュリティが強化されます。
ただし、デバッグモードを無効にすると、home.ctp
にエラーが表示されます。 この手順をこのチュートリアルの目的のみで完了した場合は、デバッグモードを無効にしたまま、ホームページを記事一覧インターフェースにリダイレクトできます。 これは、home.ctp
の内容を編集することで実現できます。
編集のためにhome.ctp
を開きます。
sudo nano src/Template/Pages/home.ctp
その内容を次のものに置き換えます。
src/Template/Pages/home.ctp
このHTMLは、Articles
コントローラーにリダイレクトします。 自動リダイレクトが失敗した場合、ユーザーがフォローするためのリンクもあります。
この手順では、セキュリティ上の理由からデバッグモードを無効にし、Articles
コントローラーが提供するブログ投稿リストインターフェイスにユーザーをリダイレクトすることで、ホームページのエラーを修正しました。
結論
これで、Ubuntu 18.04のLAMPスタックにCakePHPアプリケーションを正常にセットアップできました。 CakePHPを使用すると、好きなだけテーブルを含むデータベースを作成でき、データ用のライブWebエディターが作成されます。
CakePHP cookbookは、CakePHPのあらゆる側面に関する詳細なドキュメントを提供します。 アプリケーションの次のステップには、すべてのユーザーが独自の記事を作成できるようにユーザー認証を実装することが含まれます。