2006年05月20日

CakePHP:値をどうやって受け取るか

フレームワークを使うと、URL, $_GET や $_POST などの使い方が単純なPHPプログラムと異なる場合があります。検索エンジン対策としてURLから?param=123のような形を追い出すことができたり、逆にコントローラの名称が URL に含まれたりしますので、便利であると同時に最初はややこしく感じるわけです。そのあたりを、フレームワークがどうやって処理しているのか、という点を知る必要があります。

今日はこのあたりを解説してみます。

例えば、CakePHP の blog チュートリアルはそのあたりをさらっと流しているので、ここでつまづく人もいるかもしれません。

例えば、
blog のチュートリアル

http://manual.cakephp.org/chapter/18

の部分では、

/app/views/posts/index.thtml (edit links added)

の中で、

<?php echo $html->link('Edit', '/posts/edit/'.$post['Post']['id']);?>

と書いています。例を挙げれば、「10番の記事を編集したい」と言う場合には、

/posts/edit/10

という URL が生成されることになります。しかし、本当にこのアドレスで示す“実ファイル”があるわけではありません。

ところが、このリンクをクリックすると、posts_controller.php が呼ばれ、その中の edit メンバ関数が呼ばれます。

posts_controller.php 内の edit 関数は次のようになっています。

function edit($id = null)
{
if (empty($this->data))
{
$this->Post->id = $id;
$this->data = $this->Post->read();
}
else
{
if ($this->Post->save($this->data['Post']))
{
$this->flash('Your post has been updated.','/posts');
}
}
}

つまり、 $id に自動的に 10 という数字が代入されて入ってくる、ということを示しているのですが、どうしてこうなるのでしょうか?これは単純な PHP プログラムでは起こらない“現象”です。

この仕組みを理解するには、まず .htaccess を開いてみることが必要です。
この中には mod_rewrite という機能を使っています。

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
</IfModule>

上記の命令により、「もし、送信された URL に該当するファイルがないのであれば、“index.php?url= のあとに送信されたURLを追加した形”に変更しなさい」という処理が実行されることになります。

つまりこの機能によって、
/posts/edit/10
という URL は、実際のファイルが存在しないので、
index.php?url=posts/edit/10
というURLに“変換”されることになります。

それにより、Cake の index.php が呼ばれ、フレームワークが読み込まれ、URL が解釈されて、該当するモジュール(この場合は、postsコントローラのeditアクション)に処理が振り分けられ、引数(今回は10)が渡されることになります。

では、「二つ以上の引数を渡したい」場合には、どうすればよいのでしょうか?答えは、「スラッシュを足して、単純にURLに足していけばよい」ということになります。つまり、

/posts/edit/10/1/2/ ...

とすれば、posts_controller.php の edit メソッド内で、

function edit($id = null, $sono2 = null, $sono3 = null, .....)
{

などのように設定しておくと、
$id   には 10 が入力される。
$sono2 には 1 が入力される。
$sono3 には 2 が入力される。

などのように延々と引数を増やすことができます。基本としてはこの形でほとんどの場合、処理できると思います。

では、これまでの、 index.php?test=1&test2=2&test3=3 という形は使えないのか、というとそういうわけでもありません。

/posts/edit/10/1/2?test=1

とした場合には、

$x = $_GET['test'] とすれば、$x のなかに 1 が入ってきます。

ためしに、
function edit($id = null, $id2 = null, $id3 = null)
{
echo "** url=".$_GET['url']."<BR>";
echo "** id=".$id."** id2=".$id2."** id3 = ".$id3."<BR>";
echo "** test=".$_GET['test']."<BR>";
echo "** this->params".var_dump($this->params)."<BR>";

などのように付け足して、どんな値が入ってきているのかを見てみると、かなり具体的に把握できると思います。

Cake のURLの変換処理を把握するためには、
.htaccess
index.php
object.php
bootstrap.php
dispatcher.php
などのファイルがかかわってきますので、ご自分で参照されることをお勧めします。

メーリングリストに流れた問い合わせとしては、
・パラメータの数によって、コントローラを変えることはできないか
・SEO対策として、スラッシュの数を減らす(データをくっつける)ことができるか
・言語別の振り分け
などもありました。

特に、何か変則的なことをやりたい時などは、bootstrap.php に処理を追加することができます。












posted by SDozono at 12:47| 東京 🌁| Comment(0) | TrackBack(0) | CakePHP | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス: [必須入力]

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック
WebとCTI、VoIP技術の高みを目指して - 技術者の24時間
×

この広告は180日以上新しい記事の投稿がないブログに表示されております。