感謝のプログラミング 10000時間

たどり着いた結果(さき)は、感謝でした。

PHPの参照と関数についてちゃんと勉強してみる。

スポンサーリンク

関数って何?

関数とは、再利用できそうな処理をひとまとめにして名前をつけたものだ。
PHPの関数の構文は以下の通り。

function 関数名(引数, 引数) {
	//処理の中身
}

実際に例を作ってみる。

<?php

function add ($num1, $num2) {
    return $num1 + $num2;
}

//使ってみる
$org_num = 100;
$org_num2 = 200;

$answer = add($org_num, $org_num2);

echo "答え:" . $answer, PHP_EOL;
echo "元のorg_num:" . $org_num, PHP_EOL;
echo "元のorg_num2:" . $org_num2, PHP_EOL;

この中ではadd($num1, $num2)というのが関数となっていて、
returnというのが呼び出し元に値を返すキーワードだ。

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

$ /usr/bin/php test.php
答え:300
元のorg_num:100
元のorg_num2:200

参照って何?

パーフェクトPHPの定義を借りよう。

参照とは、ある値を指し示すものを言います。別の言い方をすると、変数のもつある値の格納領域を指し示す、別の名前を持つ変数のことを参照と言います。

これでわかるだろうか?
俺は駆け出しの頃、C言語とかで似たような説明を読んだが、これだけの説明ではよくわからなかった。

なので、実際にサンプルを見ていこう。
見れば、きっとわかる!

$a = 10;
$b =& $a; //$aを見る
$c = $a;  //$aの値がコピーされる

echo "cの値は:" . $c ,PHP_EOL;

$b = 50;
echo "bに50を代入したら、aはどうなる?:" . $a, PHP_EOL;
echo "cは相変わらず・・・" . $c, PHP_EOL;

これを実行した結果は、こうなる。

cの値は:10
bに50を代入したら、aはどうなる?:50
cは相変わらず・・・10

「=&」というのは参照代入演算子といって、$aの参照を代入することができる。
「=」だと、$aの値がコピーして渡される。

パーフェクトPHPの図をお借りして、解説を加えると、こんな感じ。
f:id:sho322:20131212230328j:plain
パーフェクトPHP、本当にわかりやすいです。

関数に渡す引数を参照で受け取る

最初の足し算の例で、引数を参照渡し版に書き換えてみよう。
関数に参照を渡す時は、

function hoge(&$var, &$var2) {}

のように、引数に「&」をつける。
では、サンプルを見てみよう。

<?php
function add (&$num1, &$num2, &$answer) {
    $answer = $num1 + $num2;
}

//使ってみる
$org_num = 100;
$org_num2 = 200;
$answer;

//$answer = add($org_num, $org_num2);
add($org_num, $org_num2, $answer);

echo "答え(answer):" . $answer, PHP_EOL;
echo "元のorg_num:" . $org_num, PHP_EOL;
echo "元のorg_num2:" . $org_num2, PHP_EOL;

これを実行すると、

$ /usr/bin/php test.php
答え(answer):300
元のorg_num:100
元のorg_num2:200

このように、$answerの値が関数の中で書き換わっていることがわかる。
これを参照渡しにしなければ、元の値には何も影響を与えない。

関数から参照を返す

関数の返り値に参照を用いたい場合は、関数名の前に&をつけて関数名を定義する必要がある。
「関数名の前」なので要注意。

<?php

function &add (&$num1, &$num2, &$answer) {
    $answer = $num1 + $num2;
    return $answer;
}

//使ってみる
$org_num = 10;
$org_num2 = 20;
$answer = 70;

//このreturn_refには$answerへの参照が返ってきてるハズ
$return_ref =& add($org_num, $org_num2, $answer);

echo "答え(answer):" . $answer, PHP_EOL;
echo "元のorg_num:" . $org_num, PHP_EOL;
echo "元のorg_num2:" . $org_num2, PHP_EOL;

$return_ref = 777;
echo "return_refに777を代入したら、変数answerはどうなる?". $answer, PHP_EOL;

上記は関数名の前に「&」をつけていることに注目。
で、return_refに777を代入したら、なんと$answerの値がちゃんと書き換わっていること(=参照が渡されたこと)が分かる。

$ /usr/bin/php test.php
答え(answer):30
元のorg_num:10
元のorg_num2:20
return_refに777を代入したら、変数answerはどうなる?777

読んだ本

パーフェクトPHP (PERFECT SERIES 3)

パーフェクトPHP (PERFECT SERIES 3)

パーフェクトシリーズはいつも大切なことを教えてくれる。
何か困ったらいつもパーフェクトシリーズが助けてくれる。
読めば読むほど味が出る素敵な本。おかげで苦手なPHPが少し好きになれそう。