今回は関数の呼び出しをメインに説明していきます。関数の内部で関数自身を呼び出したり、関数内部の処理は呼び出し元から渡された関数を使って行うことができます。そういった色々な方法を学習しましょう。
4つの関数呼び出しのパターン
通常の関数名を指定した呼び出し方法の他に、次の4つのパターンがあります。これらを覚えることで柔軟性のあるプログラムを作成できます。
再帰関数
再帰関数は関数の中でその関数自身を呼び出すこと行います。例えばサブフォルダ(サブディレクトリ)を順番に辿る場合や数値の階乗を求めるような場合などに使います。関数処理の中で自分自身を呼び出すことを再帰呼び出しといいます。
function recursive($n){
if($n != 0){
return $n * recursive($n - 1);//関数自身を呼び出す
}
return 1; //終了条件を設定する
}
$res = recursive(5);
print $res; //120
可変関数
変数に関数名を代入しておき、$変数名()で呼び出します。
function getNum($a = 5,$b){
return $a + $b;
}
$func = 'getNum';
$num = $func(1,2);//getNum関数を呼び出します
print $num;
高階関数
ざっくり言えば関数を引数や戻り値として扱う関数です。繰り返し処理などの大枠としての機能だけを高階関数としておき、具体的な処理は呼び出し側で決めることができます。2つの関数を定義しておき、1つの関数から処理を行う関数を呼び出す流れになります。
高階関数を使うことによって、共通する利用する機能だけを定義しておき具体的な処理内容を呼び出し元に任せることができます。実際にソースコードを記述して理解していきましょう。
高階関数を定義する
function manipulate($data, $func){
foreach($data as $key => $value){
$func($key, $value);
}
}
manipulate関数で引数の1つ目に配列、2つ目に関数を指定します。その関数の中で配列の中身を1つずつ取り出して$funcの中にある下請け関数を呼び出してます。
高階関数を利用する側のコード
function show($index, $value){
print $index + 1 . 'つ目:' . $value . '<br>';
}
配列要素を順に出力するだけのソースを記述しました。配列の中身は直接代入しましょう。
$ary = array(1,2,3,4,5);
ではこれらをつなぎ合わせて高階関数を利用するプログラムを作成しましょう。
高階関数を動かしてみる
<?php
function manipulate($data, $func){
foreach($data as $key => $value){
$func($key, $value);
}
}
function show($index, $value){
print $index + 1 . 'つ目:' . $value . '<br>';
}
$ary = array(1,2,3,4,5);
//高階関数の呼び出し
manipulate($ary, 'show');
?>
高階関数に配列と関数名を引き渡して、その高階関数では具体的な処理は下請けのshow関数に丸投げしてますね。こういった風に高階関数を利用します。
匿名関数
その場限りでしか使わない関数であれば、定義して呼び出しという手順は必要ないです。関数を使いたいところに直接関数定義を埋め込みます。これによって関数名を指定する必要がなくなります。
せっかくなので先ほど学習した高階関数と併せてコードを記述してみましょう。
まずは匿名関数を定義してみます。
function($index, $value){
print $index + 1 . 'つ目:' . $value. '<br>';
}
高階関数の学習で記述した下請けの関数の名前を取っ払って匿名関数にしました。
高階関数に匿名関数を引き渡します。
<?php
function manipulate($data, $func){
foreach($data as $key => $value){
$func($key, $value);
}
}
$ary = array(1,2,3,4,5);
//高階関数の呼び出し
manipulate(
$ary,
function($index, $value){
print $index + 1 . 'つ目:' . $value . '<br>';
}
);
?>
こういった関数を使っていくことでコードが短くなったり読みやすくなります。匿名関数に関しては名前がないので名前の衝突もなくなるメリットがあります。
コメント