LoginSignup
34
35

More than 5 years have passed since last update.

CakePHP3ハンズオン用

Last updated at Posted at 2014-11-20

はじめに

このハンズオンは、次の宿題をやった人を前提にしています。

ひよこソン宿題 - Qiita

上記宿題をしていなくても問題ありませんが、次の点は注意してください。

  • XAMPPがインストールされ、Apache, MySQLが起動している前提で説明する。
  • fuga/index.phpと記述した時は、XAMPPインストールフォルダ配下のhtdocsフォルダの中のという前提で説明する。
  • 確認は、ブラウザでhttp://localhost/fuga/index.phpのようにアクセスして確認する前提で説明する。
  • 最後の方で、Bootstrapを使う。
  • 最後の方で、jQueryを使う。

PHPの基本、参考サイト

なんといってもまずは本家を参照すべし。
PHP マニュアル
ある程度感じがつかめたら、
PHP: The Right Way で正しいとされるやり方を知っておく。

参考:CakePHPのコーディング規約

以下、本家サイトからの引用で主な書き方を紹介。

絶対マスターしよう

コメント

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 <...>のようなエラーがでたら、
次のコマンドにする(詳細)。
bash
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/

に接続して、

cakephp3.png

というような画面になればOKである。この画面になにがしかのエラーが出ている場合はそれを修正する。
サーバーを停止するときはコントロールキーを押しながらCを押す。

恐らくは以下のメッセージがでていると思うので、DBの設定を行う。

CakePHP is NOT able to connect to the database.
vim config/app.php

として、エディタを起動し、以下のデータベース接続情報を編集する。
testを書く人はテスト用データベース接続情報も入れておくとよい。

config/app.php
    '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アイコンをクリックしてみる。

cakephp3-2.png

ブラウザの最下部に黄色のメニューバーが表示されるので、クリックして内容を確認する。
Sql Logではこのページで実行されたクエリーを確認できる。

変数に何が入っているのか手っ取り早く確認したい時は、

debug($article);

のように書けばよい。

debug($query = $this->Articles->find());

のように書けばこのfindメソッドで生成されるSQLも確認できる。

デバッグログ(ファイル)に出力したい時は、
以下を追加しておいて、

use Cake\Log\Log;

出力したい場所で以下のように書く。

Log::write('debug', print_r($article, true));

例えば以下のようにコントローラのviewメソッドにデバッグログ書き出しを仕込んでみると、

src/Controller/ArticlesController.php
    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クラスを追加する場合は、

src/Template/Articles/add.ctp
    <?= $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/

34
35
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34
35