【CakePHP】リダイレクトで別ページに遷移する方法(redirect/header)

こんにちは!フリーランスのノムラです。

redirectって使ってますか?

redirectは処理が終わった後にトップ(index)ページへ戻る場合などによく使われます。

この記事では、redirectについて

  • redirectとは
  • PHPでのredirect
  • リダイレクト(redirect)の使い方

という基本的な内容から、

  • リダイレクト(redirect)のその他の使い方

など応用的な内容についても解説していきます。

今回はredirectについて、使い方をわかりやすく解説します!

目次

リダイレクト(redirect)とは

リダイレクトとは、アクセスしたときに別のページに遷移させることができる機能です。

PHPではheader関数、CakePHPではredirect関数が用意されています。

PHPのリダイレクト(header関数)

PHPでフレームワークを使わずにリダイレクトを行う場合は、header関数の”Location:” ヘッダを使います。

ファイルの最上部に、遷移したいURLを指定することでリダイレクトを行うことができます。

<?php
    header('Location: https://www.sejuku.net/blog/');
    exit();
?>

exit()で、それより下にある処理を、ページ遷移後に行わないようにしましょう。

このあと解説するCakePHPのredirect関数では、コントローラーとアクションを指定して簡単にリダイレクトを行うことができます。

また、リダイレクト先に値を渡すことや、クエリー文字やハッシュを使うこともできます。

どんなときに使うのか

ページにアクセスした時、別ページにとばされてしまうリダイレクトですが、実際のシステムではどのような場面で使われているのでしょうか。

具体的な例として以下のような場合に使われています。

1.ログイン画面への誘導

ログインしなければ見れないページにアクセスしようとした際は、ログインしていなかった場合にログイン画面へ遷移するようリダイレクト処理を行います。

2.新しいサイトURLに誘導

WEBサイトを新しくした際、古いURLにアクセスした人を新しいサイトに遷移するようにしたいときもリダイレクトを使うことができます。

3.処理が終わった後トップページへ戻る

ユーザの登録時に必要な情報を入力し、登録が正常に完了した場合、トップページに遷移する場合などもリダイレクトを使うことがあります。

この他にも、わたしたちが意識していないところでリダイレクトが使われている場面がたくさんあります。

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

redirect関数は引数に連想配列をとり、連想配列内で転送先のcontrolleractionを指定することができます。

基本的な使い方

redirect関数はAppControllerクラスを継承したクラス内で使用します。

redirect関数を使う場合は、下記のように記述します。

redirect関数の記述方法:

return $this->redirect(['controller' => 'コントローラ名', 'action' => 'アクション名']);

それではサンプルプログラムを確認していきましょう。

このサンプルプログラムでは「CakePHP 3.4 Red Velvet Cookbook」サイト内の「ブログチュートリアル」に沿って作成されたblogアプリケーションを使用しています。

※編集部注※
2019年現在、CakePHPはバージョンが3.7に上がりましたが、同様のブログチュートリアルが掲載されています。

このチュートリアルではアプリの名称をblogとして、CakePHPをインストールしています。その関係で、アプリの実行URLはドメイン/CakePHPのパス/blogとなります。

以下、アプリの実行アドレスを実行結果 URL「/blog」のように表記しますので、ご了承ください。
※編集部注※

参照:CakePHPブログチュートリアル https://book.cakephp.org/3.0/ja/tutorials-and-examples/blog/blog.html

テーブル「articles」を作成後、bakemodelを作成しています。

SQLクエリ:

CREATE TABLE articles (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(50),
    body TEXT,
    created DATETIME DEFAULT NULL,
    modified DATETIME DEFAULT NULL
);

/*テスト用記事*/
INSERT INTO articles (title,body,created)
    VALUES ('タイトル', 'これは、記事の本文です。', NOW());
INSERT INTO articles (title,body,created)
    VALUES ('またタイトル', 'そこに本文が続きます。', NOW());
INSERT INTO articles (title,body,created)
    VALUES ('タイトルの逆襲', 'こりゃ本当にわくわくする!うそ。', NOW());

bakeの実行例(linux):

bin/cake bake model articles

サンプルプログラムは「src/Controller/ArticlesController.php」に記述しています。

bakeで ArticlesController クラスを作成しています。

bakeの実行例(linux):

bin/cake bake controller articles

src/Controller/ArticlesController.php:

<?php
namespace AppController;

use AppControllerAppController;

class ArticlesController extends AppController
{

    public function index()
    {
        $this->set('articles', $this->Articles->find('all'));
    }

    public function view($id = null)
    {
        $this->set('article', $this->Articles->get($id));
        
        if ($this->request->is('post')) {
            return $this->redirect(['action' => 'index']);
        }
    }
}

src/Template/Articles/index.ctp:

<h1>Blog articles</h1>
<table>
    <tr>
        <th>Id</th>
        <th>Title</th>
        <th>Created</th>
    </tr>

    <?php foreach ($articles as $article): ?>
    <tr>
        <td><?= $article->id ?></td>
        <td>
            <?= $this->Html->link($article->title, ['action' => 'view', $article->id]) ?>
        </td>
        <td>
            <?= $article->created->format(DATE_RFC850) ?>
        </td>
    </tr>
    <?php endforeach; ?>
</table>

src/Template/Articles/view.ctp:

<h1><?= h($article->title) ?></h1>
<p><?= h($article->body) ?></p>
<p><small>Created: <?= $article->created->format(DATE_RFC850) ?></small></p>

<?php
    // FormHelperを使ったReturnボタンの作成
    echo $this->Form->create();
    echo $this->Form->button(__('Return'));
    echo $this->Form->end();
?>

ルートの設定は以下のとおりです。

config/routes.php:

<?php

use CakeRoutingRouteBuilder;
use CakeRoutingRouter;
use CakeRoutingRouteDashedRoute;

Router::scope('/', function (RouteBuilder $routes) {
    // ルートの設定
    $routes->connect('/', ['controller' => 'Articles', 'action' => 'index']);

    $routes->fallbacks(DashedRoute::class);
});

実行結果 URL「/blog」:

20170711index

実行結果 URL「/blog/articles/view/1」:

20170711view1

このサンプルプログラムでは、URL「/blog」で各ブログのタイトル名をクリックすると、各ブログのviewページに移動します。

ブログの各viewページでReturnボダンを押すと、redirect関数の引数の設定によりURL「/blog」に転送されます。

なお、URLの先頭が「https://」のようにSSLにより暗号化される場合はリダイレクトの際にサイトが表示されずエラーが表示されることがあります。

その場合は、後述の絶対URLを指定する方法でリダイレクト先を指定する必要がありますので、注意して下さい!

また、先ほどbakemodelcontrollerを作成しました。

bakeの詳しい説明についてはこちらを参照してくださいね。

「src/Template/Articles/view.ctp」ではFormHelperを使用しています。

FormHelperの詳しい説明についてはこちらを参照してくださいね。

actionにデータを渡す方法

redirect関数を使ってactionデータを渡すための記述方法は下記のようになります。

アクションにidデータを渡す記述方法:

return $this->redirect(['action' => 'アクション名', $id]);

それではサンプルコードで確認していきましょう。

src/Controller/ArticlesController.php:

<?php
namespace AppController;

use AppControllerAppController;

class ArticlesController extends AppController
{

    public function index()
    {
        $this->set('articles', $this->Articles->find('all'));
    }

    public function view($id = null)
    {
        $this->set('article', $this->Articles->get($id));
        
        if ($this->request->is('post')) {
            return $this->redirect(['action' => 'view', 3]);
        }
    }
}

実行結果 URL「/blog/articles/view/3」:

20170711view3

このサンプルプログラムでは、redirect関数の引数の連想配列内の要素に「3」を記述し、アクション「view」にidデータ「3」を渡しています。

ブログの各viewページでReturnボダンを押すと、redirect関数の引数の設定によりURL「/blog/articles/view/3」に転送されます。

引数に相対パスや絶対パスを指定する方法

redirect関数は引数に相対パスまたは絶対パスを指定することもできます。

src/Controller/ArticlesController.php:

<?php
namespace AppController;

use AppControllerAppController;

class ArticlesController extends AppController
{

    public function index()
    {
        $this->set('articles', $this->Articles->find('all'));
    }

    public function view($id = null)
    {
        $this->set('article', $this->Articles->get($id));
        
        if ($this->request->is('post')) {
            return $this->redirect('/articles');
        }
    }
}

このサンプルプログラムでは、redirect関数の引数に相対URLを指定しています。

ブログの各viewページでReturnボダンを押すと、redirect関数の引数の設定によりURL「/blog/articles」に転送されます。

絶対URLを使ったサンプルは次のようになります。Returnボダンを押すと侍エンジニアブログのトップページに転送されます。

また、URLの先頭が「https://」のようにSSLにより暗号化されるサイトへリダイレクトする場合の記述例となります。

src/Controller/ArticlesController.php:

<?php
namespace AppController;

use AppControllerAppController;

class ArticlesController extends AppController
{

    public function index()
    {
        $this->set('articles', $this->Articles->find('all'));
    }

    public function view($id = null)
    {
        $this->set('article', $this->Articles->get($id));
        
        if ($this->request->is('post')) {
            return $this->redirect('https://www.sejuku.net/blog/');
        }
    }
}

リダイレクト(redirect)のその他の使い方

redirectはその他にも、名前付きパラメータを渡したり、引数にクエリー文字列とハッシュを使うこともできます

名前付きパラメータを渡す方法

redirect関数は引数に名前付きパラメーターを渡すこともできます。

記述例は下記のようになります。

名前付きパラメーターを渡す記述例:

return $this->redirect(['controller' => 'Orders', 'action' => 'confirm', 'product' => 'pizza', 'quantity' => 5]);

この場合は、URL「/blog/orders/confirm?product=pizza&quantity=5」(架空のURL)に転送されます。

クエリー文字列やハッシュを使う方法

redirect関数は引数にクエリー文字列ハッシュを使うこともできます。

クエリー文字列とハッシュを使う記述例:

return $this->redirect([
    'controller' => 'Orders',
    'action' => 'confirm',
    '?' => [
        'product' => 'pizza',
        'quantity' => 5
    ],
    '#' => 'top'
]);

この場合は、URL「/orders/confirm?product=pizza&quantity=5#top」(架空のURL)に転送されます。

まとめ

ここでは、redirect関数の使い方について説明しました。

redirectは処理が終わった後に別のページへ移動する場合などによく使われます。

使いこなすことができるように、この記事を何度も参考にして下さいね!

この記事を書いた人

WEBエンジニアをやっています。
プログラミング初心者にもわかりやすく解説ができるよう頑張ります。

目次