更新履歴
更新日 | 更新者 | 更新内容 |
---|---|---|
2021/7/19 | JJI | 全体的に文章が分かりやすくなるように修正。 配列の表示関数のサンプルプログラムを追加 |
2021/8/18 | JJI | ・サンプルプログラムの実行結果に画面の画像を追加 |
はじめに
この記事では理解が難しいコールバック関数について書いています。
コールバック関数は一言でいうと次の通りです。
コールバック関数とは、関数を呼び出す場合に引数などで指定された別の関数のことです。
呼び出し元の関数に指定された別の関数が呼び出し元に返すように登録されるので、コールバック関数と呼ばれます。
上記の内容だけだと分かりにくいと思うので、この記事ではPHPで提供されるコールバック関数の使い方、使用する場面、サンプルプログラムを載せて説明します。
コールバック関数
PHPではコールバック関数の呼び出し方法として、「可変関数」、「無名関数」、「アロー関数」が提供されています。
コールバック関数はフレームワーク、ライブラリの機能を後から拡張できる仕組みとして使用されることが多いです。
WordPressのプラグインもコールバック関数を使用し、後から自由に機能を拡張できるようになっています。
もう少し分かりやすい例として次のように配列を表示する場合にコールバック関数が便利であることについて説明します。
配列の要素番号:$i、配列のキー:$code、配列の値:$valueを表示する場合、次のように色々な表示方法が考えられます。
- [$i]:$value:をスペース区切りで表示する
- [$i]:$value:を<br>\n区切りで表示する
- [$i]:$code: :$value:をスペース区切りで表示する
- [$i]:$code: :$value:を<br>\n区切りで表示する
上記の1から4を関数にした場合、次のサンプルプログラム集で書いているようにそれぞれを関数で書く必要があります。
別の方法で配列を表示したいことがあった場合、さらに同じような関数を増やす必要があり、関数を新しく作る手間が増えたり、同じような関数があることにより分かりにくかったりします。
それであれば、関数の呼び出し元で配列を表示する関数を作り、関数に渡すようにしてもらい、関数側は呼び出し元の関数を呼び出すだけでいろいろな配列の表示ができるようになります。
この呼び出し元で関数側に呼び出してもらう関数がコールバック関数です。
配列の表示関数をコールバック関数にしている例は「サンプルプログラム2」を見てください。
プログラムの初心者はコールバック関数を自分で作ることはないと思います。
プログラムの理解が進んでフレームワーク、ライブラリなどを利用したり、汎用的な共通関数を作ったりする場合にコールバック関数を使うかもしれません。
そのため、今はコールバック関数とは何かということを理解するだけで大丈夫です。
PHP標準関数
PHPの標準でもコールバック関数が使用できる関数としてusort関数があります。
構文は次の通りでコールバック関数にソート関数を指定できます。
usort関数はuser sortの略になっていると思います。
usort( array &$array , callable $callback ) : bool
項目 | 説明 |
---|---|
&$array | ソートを行う配列を指定する |
$callback | ソートを行うコールバック関数を指定する |
usortの使用方法は次のPHPマニュアルに詳しく載っています。
サンプルプログラム
サンプルプログラム1
usort関数だと少し難しいかもしれないため、もっと簡単なサンプルプログラムを紹介します。
可変関数、無名関数を使用して引数で渡された文字列を連結して表示する関数をコールバック関数にしています。
<?php
// 引数の値への厳密な型付け
declare(strict_types = 1);
echo "【PHP】関数<br>\n";
echo "【引数】コールバック関数<br>\n";
// コールバック関数を文字列で直接指定する
output_call("日本語", "echo_func1");
output_call("English", "echo_func2");
// 可変関数で指定する
$call_func ="echo_func1";
output_call("可変関数", $call_func);
// 無名関数で指定する
$call_arrow_func = function(string $param) :void {
echo $param . " " . "arrow function<br>\n";
};
// 無名関数の呼び出し
output_call("無名関数", $call_arrow_func);
// コールバックを呼び出す関数
function output_call(string $param1, callable $call) : void {
$call($param1);
echo "<br>\n";
}
// コールバック関数1
function echo_func1(string $str) :void {
echo $str . " ハローワールド1<br>\n" ;
}
// コールバック関数2
function echo_func2(string $str) :void {
echo $str . " " . $str . " Hello World!<br>\n" ;
}
?>
実行結果は次の通りです。
output_call()関数の引数で指定したコールバック関数が呼び出されていることが分かります。
・画面

・HTML
【PHP】関数<br>
【引数】コールバック関数<br>
日本語 ハローワールド1<br>
<br>
English English Hello World!<br>
<br>
可変関数 ハローワールド1<br>
<br>
無名関数 arrow function<br>
<br>
サンプルプログラム2
1次元配列の表示をコールバック関数にしているサンプルプログラムです。
サンプルプログラム1よりは具体的な例であり、分かりやすいと思います。
<?php
// 引数の値への厳密な型付け
declare(strict_types = 1);
// 共通ライブラリの読み込み
require_once __DIR__ . "../../../lib/sample_common.php";
echo "ファイル名:" . basename(__FILE__) . "<br>\n";
echo "【PHP】コールバック関数のサンプル<br>\n";
// 1次元連想配列
$ary1 = [
"first_name" => "山田", "second_name" => "太郎", "age" => 35,"seibetsu" => "男性"
];
// コールバック関数1
$func1 = function($i, $key, $val) : string {
$str = "";
if($i !== 0) {
$str = " ";
}
return $str . "[$i]:$val:";
};
// コールバック関数2
$func2 = function($i, $key, $val) : string {
return "[$i]:$val:<br>\n";
};
// コールバック関数3
$func3 = function($i, $key, $val) : string {
return "[$i]:$key:$val:<br>\n";
};
echo_sample_array($ary1, "コールバック関数1", $func1);
echo_sample_array($ary1, "コールバック関数2", $func2);
echo_sample_array($ary1, "コールバック関数3", $func3);
// コールバック関数を呼び出す関数
function echo_sample_array(array $ary, string $func_name, callable $func) :void {
$i = 0;
echo "${func_name}<br>\n";
foreach($ary as $key => $val) {
// ここで引数で渡されたコールバック関数を呼び出す
echo $func($i, $key, $val);
$i++;
}
echo "<br>\n";
}
?>
実行結果です。
・画面

・HTML
ファイル名:sample02_02_19.php<br>
【PHP】コールバック関数のサンプル<br>
コールバック関数1<br>
[0]:山田: [1]:太郎: [2]:35: [3]:男性:<br>
コールバック関数2<br>
[0]:山田:<br>
[1]:太郎:<br>
[2]:35:<br>
[3]:男性:<br>
<br>
コールバック関数3<br>
[0]:first_name:山田:<br>
[1]:second_name:太郎:<br>
[2]:age:35:<br>
[3]:seibetsu:男性:<br>
<br>
最後に
この記事では、コールバック関数が分からない方に利用する場面、サンプルプログラムを使って、コールバック関数について説明しました。
最初は理解が難しいと思いますが、この記事を参考にしたり、実際にサンプルプログラムを作ったりしていくうちに理解できるようになると思います。
コメント