はじめに
このハンズオンは、次の宿題をやった人を前提にしています。
上記宿題をしていなくても問題ありませんが、次の点は注意してください。
- XAMPPがインストールされ、Apache, MySQLが起動している前提で説明する。
-
fuga/index.php
と記述した時は、XAMPPインストールフォルダ配下のhtdocsフォルダの中のという前提で説明する。 - 確認は、ブラウザで
http://localhost/fuga/index.php
のようにアクセスして確認する前提で説明する。 - 最後の方で、Bootstrapを使う。
- 最後の方で、jQueryを使う。
PHPの基本、参考サイト
なんといってもまずは本家を参照すべし。
PHP マニュアル
ある程度感じがつかめたら、
PHP: The Right Way で正しいとされるやり方を知っておく。
参考:[CakePHPのコーディング規約] (http://book.cakephp.org/3.0/en/contributing/cakephp-coding-conventions.html)
以下、本家サイトからの引用で主な書き方を紹介。
絶対マスターしよう
コメント
echo 'テストです'; // C++型の単一行用のコメント
/* 複数行用のコメント
もう一行分のコメント */
echo 'もうひとつのテストです';
echo '最後のテストです'; # シェル型の単一行用のコメント
文字列(結合と式展開)
var $result = "foo" . "bar";
echo "Result is {$result}"; // Result is foobar
出力
echo "Hello";
echo $result;
$a = array('apple', 'orange', 'grape');// 配列
print_r($a);
$results = print_r($a, true);// 変数に入れられる
var_dump($a);
シングルクォート内の文字列
シングルクォートで囲まれた文字列では式展開されない
$str = "123";
echo "$str"; // 123
echo '$str'; // $str
echo "\n"; // 改行
echo '\n'; // \n
演習
hello/index.php
を作成し、Hello, PHP
と表示される画面を作成する。
できたら、上記を参考に色々試してみる。
関数
function makecoffee($type = "cappuccino") {
return "Making a cup of $type.\n";
}
echo makecoffee("espresso");
配列とハッシュ
$array = array(
"foo" => "bar",
"bar" => "foo",
);
// PHP 5.4 ではこのようにも書けます
$array = [
"foo" => "bar",
"bar" => "foo",
];
// 数値添字配列でキーを省略した書き方
$array = array("foo", "bar", "hello", "world");
$array = ["foo", "bar", "hello", "world"];
配列からリストに。
$info = array('コーヒー', '茶色', 'カフェイン');
list($drink, $color, $power) = $info;
範囲指定で配列に。
// array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
foreach (range(0, 12) as $number) {
echo $number;
}
配列をカンマで連結して文字列に。
$array = array('lastname', 'email', 'phone');
$comma_separated = implode(",", $array);
echo $comma_separated; // lastname,email,phone
演習
fizzbuzz/index.php
を作成し、1から100まででFizzBuzzが表示される画面を作成する。
ループや分岐は以下参考。
できたら、関数、配列、ハッシュをあえて使ってやってみる。
ちなみに、CakePHPでは配列、ハッシュとforeachを頻繁に使うので、慣れておくこと。
理解はしておこう
クラス
class SimpleClass {
// プロパティの宣言
public $var = 'a default value';
// メソッドの宣言
public function displayVar() {
echo $this->var;
}
}
コンストラクタ
class BaseClass {
function __construct() {
print "In BaseClass constructor\n";
}
}
class SubClass extends BaseClass {
function __construct() {
parent::__construct();
print "In SubClass constructor\n";
}
}
class OtherSubClass extends BaseClass {
// BaseClass のコンストラクタを継承します
}
// In BaseClass constructor
$obj = new BaseClass();
// In BaseClass constructor
// In SubClass constructor
$obj = new SubClass();
// In BaseClass constructor
$obj = new OtherSubClass();
クラス継承
class ExtendClass extends SimpleClass {
// 親クラスのメソッドを再定義
function displayVar() {
echo "Extending class\n";
parent::displayVar();
}
}
$extended = new ExtendClass();
$extended->displayVar();
CakePHP3インストールと設定
参照:http://book.cakephp.org/3.0/en/installation.html
最初にcomposer(phpのライブラリ管理システム)をインストールする。
curl -s https://getcomposer.org/installer | php
composerのインストールといっても、上記コマンドで、今いるディレクトリにcomposer.pharというファイルが落ちてくるだけ。
これを使って、通常は自分がインストールしたいライブラリ情報を記入したcomposer.jsonファイルを同じ階層において、
php composer.phar install
とすることでライブラリをインストールする。
composer.jsonの例。
{
"require": {
"monolog/monolog": "1.2.*"
}
}
composerについて詳しく知りたい方はこちらから。composer
*注)Macの人はmv composer.phar /usr/local/bin/composer
としておけば、php composer.phar
部分をcomposer
に変えられるし、パスを意識しないでいいので、おすすめ。
OAuthエラー対応参考URL
が、ここでは
php composer.phar create-project --prefer-dist -s dev cakephp/app [app_name]
とする。[app_name]のところは自分で考えた名前を入れる。
上記コマンドを実行すると[app_name]ディレクトリが作られて、その中にCakePHPが設置されている。
5分くらい時間がかかるので注意。
*注)PHP Fatal error: Allowed memory size of XXXXXX bytes exhausted <...>
のようなエラーがでたら、
次のコマンドにする(詳細)。
php -d memory_limit=-1 composer.phar create-project --prefer-dist -s dev cakephp/app [app_name]
注)ここで、OSXユーザーの場合は、logsとtmpフォルダーに書き込み権限を与えておくのを忘れずに。
chmod -R 777 tmp
chmod -R 777 logs
続いて
bin/cake server
として開発用サーバーを起動する。
Welcome to CakePHP v3.0.0-beta3 Console
---------------------------------------------------------------
App : src
Path: C:\Users\yourname\project\src\
DocumentRoot: C:\Users\yourname\project\webroot
---------------------------------------------------------------
built-in server is running in http://localhost:8765/
You can exit with `CTRL-C`
というようなメッセージが出るので、ブラウザから
http://localhost:8765/
に接続して、
というような画面になればOKである。この画面になにがしかのエラーが出ている場合はそれを修正する。
サーバーを停止するときはコントロールキーを押しながらCを押す。
恐らくは以下のメッセージがでていると思うので、DBの設定を行う。
CakePHP is NOT able to connect to the database.
vim config/app.php
として、エディタを起動し、以下のデータベース接続情報を編集する。
testを書く人はテスト用データベース接続情報も入れておくとよい。
'Datasources' => [
'default' => [
'className' => 'Cake\Database\Connection',
'driver' => 'Cake\Database\Driver\Mysql',
'persistent' => false,
'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' => 'nonstandard_port_number',
'username' => 'my_app',
'password' => 'secret',
'database' => 'my_app',
'encoding' => 'utf8',
'timezone' => 'UTC',
'cacheMetadata' => true,
/*
* Set identifier quoting to true if you are using reserved words or
* special characters in your table or column names. Enabling this
* setting will result in queries built using the Query Builder having
* identifiers quoted when creating SQL. It should be noted that this
* decreases performance because each query needs to be traversed and
* manipulated before being executed.
*/
'quoteIdentifiers' => false,
/*
* During development, if using MySQL < 5.6, uncommenting the
* following line could boost the speed at which schema metadata is
* fetched from the database. It can also be set directly with the
* mysql configuration directive 'innodb_stats_on_metadata = 0'
* which is the recommended value in production environments
*/
//'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'],
],
MySQL
データベースの操作にはphpMyAdminを使う方法があるが、動作が重いので、推奨しない。
XAMPPでインストールした場合は C:\xampp\mysql\bin 以下にある実行ファイルが実体なので、ここにパスを通しておけばよい。
(システム→システムの詳細設定→環境変数→Path→編集)
コマンドラインから
mysql -u root -p
パスワードを設定してない場合は、
mysql -u root
でDBに入れるので
データベース作成
CREATE DATABASE sample_db DEFAULT CHARACTER SET utf8;
ユーザー設定
GRANT ALL ON sample_db.* TO myuser@localhost IDENTIFIED BY 'password';
使用するデータベースを指定
use sample_db
あとは使いたいsqlを流せばよい。
参考:http://xref.jp/database
終了するときは
\q
もしくは
quit
演習
演習用のデータベースを作成し、接続用のユーザーを設定し、CakePHPの設定に記述して、CakePHPから接続できることを確認してみましょう。
テーブル作成
例えばブログの記事を保存するテーブルは以下のようなsqlになる。
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(50),
body TEXT,
created DATETIME DEFAULT NULL,
modified DATETIME DEFAULT NULL
);
命名規約:http://book.cakephp.org/3.0/en/intro/conventions.html
-
テーブル名は英単語の複数形で、アンダースコアを用いる。
-
テーブルには必ずidという名前のプライマリーキーを持たせる。
-
2つ以上の単語を使うフィールド名はアンダースコアで連結:first_name。
-
外部キーはその関連する「テーブル名の単数形_id」とする。
-
created と modified はお約束で、登録日時と更新日時が自動でインサート(アップデート)される。
演習
CREATE TABLE文を作成し、演習用のデータベースにテーブルを作成してみましょう。
ブログの記事とコメントなど、思いついたものをテーブルにしてみます。
BakeとMVC
bakeコマンドを使って自動で、MVC(モデル、ビュー、コントローラ)を作成します。
今回articlesテーブルが作ってあるので、それについて操作する。
コマンドラインから、
bin/cake bake model Articles
と打つ。
Welcome to CakePHP v3.0.0-beta3 Console
---------------------------------------------------------------
App : src
Path: C:\Users\yourname\project\src\
---------------------------------------------------------------
One moment while associations are detected.
Baking table class for Articles...
Baking entity class for Article...
Baking test fixture for Articles...
Baking test case for App\Model\Table\ArticlesTable ...
というような表示が出て、モデルに必要なファイルが自動生成される。
アソシエーションについては現時点のbakeではuser_idなどの命名規則に従ったフィールド名を元に自動で生成されるので、モデル作成後必ずソースを確認すること。
続いて、コントローラを作成する。
bin/cake bake controller Articles
Welcome to CakePHP v3.0.0-beta3 Console
---------------------------------------------------------------
App : src
Path: C:\Users\yourname\project\src\
---------------------------------------------------------------
Baking controller class for Articles...
Baking test case for App\Controller\ArticlesController ...
コントローラが作られる。続いてビューも同様に。
bin/cake bake view Articles
ブラウザから生成物を確認する。
http://localhost:8765/articles/
登録、編集、削除、一覧ができるようになっている。
この自動生成されたファイルを元に作っていくので、ざっくり中身を確認しておく。
演習
前項で作成したテーブルに関して、bakeコマンドでモデル、コントローラ、ビューを作成し、ブラウザから確認してみましょう。
デバッグ
登録画面(New Article)からなにかデータを登録した後、一覧画面からViewをクリックし、画面右下にあるCakePHPアイコンをクリックしてみる。
ブラウザの最下部に黄色のメニューバーが表示されるので、クリックして内容を確認する。
Sql Logではこのページで実行されたクエリーを確認できる。
変数に何が入っているのか手っ取り早く確認したい時は、
debug($article);
のように書けばよい。
debug($query = $this->Articles->find());
のように書けばこのfindメソッドで生成されるSQLも確認できる。
デバッグログ(ファイル)に出力したい時は、
以下を追加しておいて、
use Cake\Log\Log;
出力したい場所で以下のように書く。
Log::write('debug', print_r($article, true));
例えば以下のようにコントローラのviewメソッドにデバッグログ書き出しを仕込んでみると、
public function view($id = null) {
$article = $this->Articles->get($id, [
'contain' => []
]);
Log::write('debug', print_r($article, true));
$this->set('article', $article);
}
ビューにsetされている$articleはオブジェクトになっていることが分かる。
演習
前項で自動生成されたソースを見て、変数をdebugしてみましょう。
select
ここでCakePHP3のモデルについての説明。
$query = $this->Articles->find();
こういう書き方でクエリーオブジェクトなるものが作られる。
(まだSQLは実行されない)
で、
$query->all();
と書けばSQLが実行される。
つまりこれでワンセット。
$query = $this->Articles->find();
$query->all();
で、以下のように書けば
$results = $query->all();
foreach ($results as $result) {
echo $result->id;
echo $result->created;
}
とすれば取り出せる。$resultsがビューに渡されて、ビュー側でにforeach以下で値を取り出しているということ。
$query = $this->Reports->find();
foreach ($query as $result) {
echo $result->id;
echo $result->created;
}
こう書いても結果はおんなじ。all()は省略可能ってことです。
その他、クエリーのコンディション等はメソッドチェーンで記述する。以下を参照のこと。
参考:http://book.cakephp.org/3.0/en/orm/query-builder.html#selecting-data
演習
参考ページをみながら、独自のクエリーを実行するメソッドを作ってみましょう。
insert delete update
Bakeで作成したコントローラのメソッドadd, delete, edit を参考にしてください。
Form
フォームヘルパーは以下参照:
http://book.cakephp.org/3.0/en/views/helpers/form.html
大きな変更はないが、phpの配列の書き方が変わったので注意のこと。
例えば以下のようなaddフォームにBootstrapのform-controlクラスを追加する場合は、
<?= $this->Form->create($article); ?>
<fieldset>
<legend><?= __('Add Article') ?></legend>
<?php
echo $this->Form->input('title');
echo $this->Form->input('body');
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
以下のようにすればよい。
echo $this->Form->input('title', ['class' => 'form-control']);
出力結果
<input type="text" id="title" maxlength="50" class="form-control" name="title">
演習
Bootstrapを組みこんで、スタイルを適用してみましょう。
ビュー
BootstrapやjQueryを使う場合はLayoutのdefault.ctpに以下のように書いて、webroot以下のフォルダーにファイルを置けばよい。
<?= $this->Html->css('bootstrap.min') ?>
<?= $this->Html->script('bootstrap.min') ?>
詳しくは、
http://book.cakephp.org/3.0/en/views.html
レイアウトを使わない時はコントローラに
$this->layout = false;
そもそもビューを使わない時は
$this->autoRender = false;
演習
ビューを使わずに、たんなるJSONデータを返すようなメソッドを作ってみましょう。
(Web APIとして利用できるので便利。)
答え:
https://gist.github.com/uedatakeshi/4856c087d105b25cc0f4
参考サイト
http://book.cakephp.org/3.0/en/contents.html
http://php.net/