[CakePHP]controllerのset()メソッド

どうやって渡しているのかきになる。フォームでの受取りしかしらないバカなもんでね。ちょっとお勉強したいのさ。
ソース
http://api.cakephp.org/view_source/controller/#line-656

うっとうしい分析

set(string $var, mixed $value)

第1引数が変数名で、第2引数が渡す値。文字列でも配列でも良い。
$oneが$varで、$valueが$twoにあたる。

controller.php
<?php
function set($one, $two = null) {
$data = array();
if (is_array($one)) {
if (is_array($two)) {
$data = array_combine($one, $two);
} else {
$data = $one;
}
} else {
$data = array($one => $two);
}

$data初期化で配列。もし、$oneが配列ならtrue以下実行。そうでないなら$oneの文字列をキーとして値を$twoにし、$dataに代入。後者の場合、$one
$oneが配列で$twoも配列なら、array_conbine()関数でコンバインしちゃう。この関数ってどちらとも要素数一緒じゃなきゃいけない。それで$oneが配列だけど$twoが配列では無い場合、$dataには$oneが入る。
パターン1:$oneと$twoが配列ならユーコンバインしちゃいなよ、で$dataの配列
パターン2:$oneは配列だけど$twoは配列じゃない、で$dataの配列
パターン3:$oneが配列ではないのなら、で$oneがキーで$twoが値となった$dataの配列
がここでできあがるわけですねー。
次。

controller.php
<?php
foreach ($data as $name => $value) {
if ($name === 'title') {
$this->pageTitle = $value;
} else {
if ($two === null && is_array($one)) {
$this->viewVars[Inflector::variable($name)] = $value;
} else {
$this->viewVars[$name] = $value;
}
}
}
}

foreach。$dataで$nameをキー、$valueを値。
if文は、もし$nameがtitleという文字列なら、$this->pageTitleに代入。
pageTitleの説明はこれ。
http://book.cakephp.org/ja/view/54/Page-related-Attributes-layout-and-pageTitle
ページタイトルはちゃんとpageTitleに入れてくれるのね。
それで、もしtitleというキーがでなくて、$twoがnullで$oneが配列ならば。つまり、set()メソッド使ったときに引数が$oneの配列だけだった場合は。$viewVarsという配列にInflectorクラスのvariableメソッドを使い、引数に$nameでその返り値をキーとし、代入は$value。
そうでなければ、外部のメソッドを参照せずに$viewVarsに$nameをキーとして$valueを代入。

えーまたまたInflectorクラスのvaroableメソッドを緊急にみなければいけなくなりました。

<?php
function variable($string) {
$string = Inflector::camelize(Inflector::underscore($string));
$replace = strtolower(substr($string, 0, 1));
return preg_replace('/\\w/', $replace, $string, 1);
}

まーた参照。関係ないけどこれって::じゃないとだめなのでしょうか。->ではダメ?

Inflector.php
<?php
function camelize($lowerCaseAndUnderscoredWord) {
return str_replace(" ", "", ucwords(str_replace("_", " ", $lowerCaseAndUnderscoredWord)));
}

//

function underscore($camelCasedWord) {
return strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $camelCasedWord));
}

camelizeメソッドは、ucwords関数は文字列の最初の小文字を大文字に。んで、$lower〜のうちにアンダースコアがあるなら半角スペースして、さらに外側のstr_replaceで半角スペースを除去。
underscoreメソッドは、preg_replace関数で$camel〜のうちに/(?<=\\w)([A-Z])/'にマッチする部分を、'_\\1'に置換。アンダースコアをつけるってことかな?で、strtolowerで全部小文字にしてます。

というわけで、variableメソッドは、まず$stringをunderscoreメソッドでマッチすればアンダースコアつけて、camelizeメソッドでアンダースコアがあったらそれを半角スペースに直し、単語のトップを大文字にしてさらに半角スペースくっつけて自己代入。
で、$replaceはsubstr関数を使い$stringの最初を取得、そしてそれをstrtolower関数で小文字に変換して$replaceに代入。
returnの部分は$stringで大文字になっている部分を$replaceに変換。引数1なんで最初です。この辺はよくわからないと思うので、
http://book.cakephp.org/ja/view/572/Class-methods
をみるといいですね。結局キーの名前をクラスメソッドっぽくしている。ただ、どういう場合にここに流れ着くのか、っていうのがわからないなあ。

まー簡略化すると、
パターン1:$nameが'title'なら、$this->pageTitleに$valueの値を代入
パターン2:$twoがnullで、$oneが配列なら$viewVarsにキーの名前をクラスメソッド?っぽくして、$valueの値を代入
パターン3:パターン2に当てはまらない場合は、$viewVarsに$nameをキーに、$valueの値を代入
で、これらを1つ1つ検査して繰り返していくということですねー。

最終的にどうやって渡しているかというと、$pageTitleと$viewVarsに値が代入されているわけで。それで、

$data = "データだよーん";
set('var', $data);

ってやると、ビューでは$varを使うことでデータだよーん、て表示できるわけですが、なんでこうなるかわからん。

あー、もしかしてどこかで、

extract($viewVars);

みたいなことやってんのかな。おそらく。これ以上はわからん。
結局ただの変数でわたしてるってことでしょう。そりゃそうだよね。まーでもやっぱり値の受け渡しってのは配列が最適みたい。