【CakePHP入門】Controllerの主な処理をまとめました!

こんにちは。ライターの亀田です。

PHPにはCakePHP以外にも様々なフレームワークが存在します。

最近では、FuelPHP、Laravelなどといった新興勢力が台頭してきています。

しかしフレームワークが違っても基本的な考え方にはさほど違いはありません

フレームワークはM(Model)V(View)C(Controller)という3つの柱があります。

このうち特にControllerは、画面出力をつかさどるViewと、データ構造を担っているModelの間を取り持つ大事な役割を担っています。

今回は特に、CakePHPのControllerに注目してその役割を説明していきます。

まずは、

・ コントローラー(Controller)とは?

で、コントローラーの基本的な使い方を紹介します。続いて

・ページネーションの使い方(Pagenation)
・セッションの使い方(session)
・デバッグの使い方(Debug)
・ログの使い方(Log)
・リダイレクトの使い方(Redirect)

で、具体的な仕組みについて言及します。

更に、応用編として

・ログイン認証の設定方法(Auth)
・コンポーネントの使い方(component)
・setメソッドの使い方
・共通処理(beforefilter)

で応用的なトピックについて取り上げることにします。

目次

コントローラー(Controller)とは?

冒頭にも説明した通りフレームワークは、ModelViewControllerという3つの要素から構成されています。

Viewは画面へのHTML出力、Modelはデータベースへのアクセスを役割としています。

Controllerは、ViewからのアクションをもとにModelにアクセスしたりするなど両者を取り持っています。

また、ユーザーがURLを入力した際に、その内容によって適切な処理をViewとModelに割り振るのも、Controllerの仕事です。

基本的な使い方

では、実際にコントローラーはどのような働きをするのでしょうか。実際に簡単な実例を以下に示します。

helloworld

まずは、helloworldが出る簡単なサンプルを見てみることにしましょう。

composerでプロジェクトを作り、以下のプログラムを入力してみましょう。

src/controller/HelloController.php

<?php 
    namespace App\Controller;
    
    use App\Controller\AppController;
    
    class HelloController extends AppController
    {
        public function index()
        {
            //変数teststrをセット
            $this->set('comment', 'HelloWorld');
        }
    }

View側の設定は、ctpファイルで行います。コントローラーの名前が「HelloController」なので、src/Templateフォルダの下に、更に「hello」というフォルダを作り、以下のファイルを置いてください。

src/Template/hello/index.ctp

<?php
//index.ctp
?>
<div>
    <h1>Helo Wrold!</h1>
    <p class="text-red"><?= $comment ?></p>
</div>

XAMPPなどを使いローカルホストでこれを表示する場合には、

http://localhost/[プロジェクト名]/hello

と入力してください。

すると、以下のように表示されます。

pic1-min

Controller(この場合は、HelloController)で、指定しているctpファイル(この場合は、index.ctp)を呼び出し、表示しています。

ctpファイルは、CakePHPで用いられるphpのテンプレートファイルで、Controllerから操作が可能です。

ここには、$commentという変数がありますが、この値を決めているのが、Controllerの以下の部分です。

$this->set('comment', 'HelloWorld');

CakePHPでは、これによって動的にページを生成します。これはどんなにページ数が多く複雑なアプリでも原則は変わりません。

データベースへのアクセスを行う場合

次に、簡単なデータベースのアクセスを行うサンプルを紹介しましょう。

CakePHPでデータベースを操作する方法は大きく分けて2通りあります。

一つはモデル(Model)を利用する方法です。

もう一つは直接SQLを実行する方法で、簡単な操作であれば、Controller内で直接SQL文を実行します。

以下にそのサンプルを紹介します。

src/Controller/DbController.php

 
namespace App\Controller;

use App\Controller\AppController;
use Cake\Datasource\ConnectionManager;
    
class DbController extends AppController {
    function index() {
        $sql = "SELECT * FROM data";
        $connection = ConnectionManager::get('default');
        $connection->logQueries(true);
        $data = $connection->query($sql)->fetchAll('assoc');
        $connection->logQueries(false); 
        $this->set('data', $data);
    }
}

src/Template/Db/index.ctp

<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        <h1>実行結果</h1>
        <table style="border:1px; width:400px;"><tr><th>ID</th><th>名前</th></tr>
        <?php
            print '';
            foreach($data as $element){
                print "<tr><td>{$element['id']}</td><td>{$element['name']}</td></tr>\n";
            }
        ?>
        </table>
    </body>
</html>

データベースのテーブルはdataにしましょう。

CREATE TABLE data(
    id int,
    name varchar(32)
);

以下のようにしてデータを追加してください。

INSERT INTO data VALUES(1,"Yamada");
INSERT INTO data VALUES(2,"Sato");
INSERT INTO data VALUES(3,"Gotou");

データベースに関する設定などは、以下を参考にしてみてください。

設定が終わったら、URLを以下のように指定してください。

http://localhost/[プロジェクト名]/db

すると、実行結果は以下のようになります。

pic2-min

データベースの内容が表示されていることが分かります。

このように、簡単なデータベースへのアクセスであれば、コントローラー内で行うことが出来ます。

ページネーションの使い方(Pagenation)

ところで、実際にCakePHPで作るアプリで使用すると、検索結果一覧や名簿の一覧などのように、一つのページ内にすべての情報が収まらない場合があります。

そのような時に便利なのが、ページネーション(Pagenation)と呼ばれる機能です。

ページネーションを行えば、こういった大量の情報を複数のページに分割することが出来ます。

Paginateとは

CakePHPでは、ページネーションを実現する方法の簡単な例を以下のように行います。

class ArticlesController extends AppController {

    public $paginate = [
        'limit' => 25,
        'order' => [
            'Articles.title' => 'asc'
        ]
    ];

    public function initialize()
    {
        parent::initialize();
        $this->loadComponent('Paginator');
    }
}

設定は、$pangenateというフィールドに設定を行います。

limitは最高ページ数で、この場合は25ページ、orderは並び順で、ここではArticlesテーブルのtitle部分を昇順で並べることを意味しています。

この設定を有効にするには、

 $this->loadComponent('Paginator');

で、Paginatorコンポーネントを読み込むことによって有効になります。

なお、ページネーションに関してより詳しく学習したい方は、以下を参考にしてください。

セッションの使い方(session)

続いて、CakePHPにおけるセッション(session)の扱い方について説明します。

セッションとは、一連の処理の始まりから終わりまでを表す概念で、そのために一時的にデータを保存する仕組みも含められます。

主にWebサイトのログイン情報や最終のアクセス情報などの保存に利用されます。

Sessionとは

CakePHPにおいては、セッション(session)はコントローラーで操作できるようになっています。

$this->request->session();

で、セッションオブジェクトが取得できます。この中に、

[キー : 値]

という組み合わせでデータを保存・取得することが可能です。

基本的な操作方法ですが、データを設定する場合は、

$this->request->session()->write($key, $value);

取得する場合は

$this->request->session()->read($key);

という風に操作します。

セッションに関して詳しく学びたい方は、以下を参考にしてみてください。

デバッグの使い方(Debug)

ウェブアプリにおいてデバッグをするにはログを残す方法が有効です。

CakePHPには、Debugという、デバッグ用のログを残す仕組みが用意されています。

Debugとは

CakePHPでDebugを使うためには、ControllerでLogクラスのdebugメソッドを使います。

まずは、以下のようにしてLogクラスを使えるようにしてください。

use Cake\Log\Log;

後は、デバッグログを発生させたい場所に以下のように記述してください。

Log::debug('debug log');

Debugについて詳しく学びたい方は、以下を参考にしてみてください。

ログの使い方(Log)

前述のDebugはシステムそのもののデバッグを行うために用意されている仕組みです。

それに対し、主にシステム運用時に何らかの不具合が発生した場合に解析する仕組みとしてログを残す必要があります。

その仕組みを用意しているのがControllerののlogメソッドです。

Logとは

logメソッドを使う方法は簡単です。

$this->log('ログの内容' [, ログレベル]);

とすれば、ログをファイルに保存することが出来ます。

ログレベルは省略でき、システムの運用ポリシーに従って決めてください。

なお、ログに関して詳しく学びたい方は、以下を参考にしてみてください。

リダイレクトの使い方(Redirect)

Webアプリでは、時々強制的なページ遷移を必要とする場合があります。

例えば、処理が終わった後にトップ(index)ページへ戻る場合などです。

このような時に有効なのがリダイレクト(Redirect)という仕組みです。

Redirectとは

CakePHPでリダイレクトを行うには、アクションの最後で、以下のように記述します。

return $this->redirect(['action' => 'index']);

これは処理終了後に、同一コントローラー内のindexに遷移することを意味します。

別のコントローラーに移る場合は、

return $this->redirect(['controller' => 'Article','action' => 'index']);

のようにします。この場合は、Articleコントローラーのindexへの遷移を意味します。

なお、CakePHPのリダイレクトについて詳しく知りたい方は、以下を参考にしてください。

ログイン認証の設定方法(Auth)

Webアプリには、ログイン認証は無くてはならない機能です。

当然のことながら、CakePHPにもその仕組み用意されています。それが、Authコンポーネントです。

Authとは

Authコンポーネントを使うには、Controllerのinitializeメソッド内で設定を行います。例えば

$this->loadComponent('Auth', [
    'loginRedirect' => [
    'controller' => 'Articles',
    'action' => 'index'
    ],
    'logoutRedirect' => [
    'controller' => 'Pages',
    'action' => 'home'
    ]
]);

とすると、ログイン時はArticlesコントローラーのindexへ、ログアウト時はPagesコントローラーのhomeへ遷移することを意味します。

なお、authを使用してユーザーを識別・認証する方法については以下で詳しく解説しています。
参考にしてみてください。

コンポーネントの使い方(component)

前述のauthのように、CakePHPではしばしばコンポーネント(component)を使用することがあります。

コンポーネントは、わかりやすく言えば外部に用意されている機能のことで、必要に応じて読み込んで利用します。

componentとは

CakePHPでコンポーネントを読み込む方法は2通りあります。

一つは、使いたいコントローラーのpublicフィールドとして、配列$componentsを宣言し、その中にコンポーネント名を書いていく方法です。例えば、

public $components = ["Auth", "Cookie"];

とすればよいのです。そして、もう一つの方法が、loadComponentメソッドで読み込む方法です。

前述のauthコンポーネントの使用方法がそれにあたります。

なお、コンポーネントはもともとCakePHPに用意されているものばかりではなく、自分でも作ることが可能です。

詳しくは以下を参考にしてみてください。

setメソッドの使い方

CakePHPにおいて、View(Template内の.ctpファイル)に値を渡すのがsetメソッドです。

このメソッドはCakePHPのControllerで大変使用頻度の高いメソッドです。

setとは

冒頭のHelloWorldのサンプルを見ればわかる通り、.ctpファイルにデータを渡すには、

$this->set('変数名', 値);

とします。

setメソッドについて詳しいことは、以下を参考にしてみてください。

共通処理(beforefilter)

最後に、Controllerの共通処理(beforefilter)メソッドについて説明します。

このメソッドは、Controllerで主に共通したい処理を記述したいときに使用します。

beforefilterとは

beforefilterメソッドは、アクションが実行される前に実行されます。

そのため、アクションを実行する前の設定などに利用されます。

具体的なコードでどのような方法でbeforefilterを使用するか見てみることにしましょう。

<?php
namespace App\Controller;
use App\Controller\AppController;
use Cake\Event\Event;
 
class BeforeController extends AppController{
    //プロパティを宣言
    public $text = 'AAA';
    
    public function beforeFilter(Event $event) {
        //値を変更する
        $this->text = 'BBB'; 
    }

    public function index() {
        $this->set('text', $this->text);
    }
}

$textフィールドの値の初期値は’AAA’です。しかし実行すると、indexアクションが実行されたときに値は’BBB’になっています。

これは、その前にbeforefilterが実行されて値が変更されるからです。

beforefilterについて詳しく知りたい方は、以下を参考にしてみてください。

まとめ

今回はCakePHPのControllerについて、以下のような流れで説明してきました。

・ コントローラー(Controller)とは?
・ページネーションの使い方(Pagenation)
・セッションの使い方(session)
・デバッグの使い方(Debug)
・ログの使い方(Log)
・リダイレクトの使い方(Redirect)
・ログイン認証の設定方法(Auth)
・コンポーネントの使い方(component)
・setメソッドの使い方
・共通処理(beforefilter)

これらを巧みに利用すれば、PHPのみでは非常に実装が難しいWebアプリを簡単に実装できてしまいます。

また、こういった仕組みはCake以外の他のPHPフレームワークでも似たような仕組みになっています。

本格的なWebアプリケーションを作りたい方は、以上の内容をしっかり学習してください。

この記事を書いた人

エンジニアとして独自の製品やサービスを開発する傍ら、エンジニア教育にも力を入れています。企業研修や専門学校での非常勤講師もしながら、独自の言語学習サイト「一週間でわかるシリーズ」を運営し、エンジニアになりた人をサポートする活動をライフワークにしています。
【一週間で学べるシリーズ】
http://sevendays-study.com/

目次