引数の規定値
仮引数に規定値を設定できる
function getArea(float $base = 5, float $height = 1):float {
return $base * $height / 2;
}
$area = getArea();//省略可能
規定値を持つ引数省略可能。 ただし省略した引数より後の引数は全て省略しなければならない。
function func($x, $y = 2, $z = 3) {
echo $x, $y, $z;
}
func(1,,3); //Parse Error この呼び出しはエラー
PHP 8.1.0 以降では、 new ClassName() 記法を使ってオブジェクトも指定できます。
function makecoffee($coffeeMaker = new DefaultCoffeeMaker){...}
echo makecoffee(new FancyCoffeeMaker);
引数/戻り値の型宣言
function getArea(float $base = 5, float $height = 1):float {
return $base * $height / 2;
}
型名 | 概要 |
---|---|
bool | 真偽値 |
float | 浮動小数点数 |
int | 整数 |
string | 文字列 |
array | 配列 |
iterable | 配列/Traversal型(= foreace 命令で利用できる型) |
callable | コールバック関数 |
object | 任意のオブジェクト |
クラス/インターフェイス名 | 指定されたクラス/インターフェイス |
mixed | 任意の型 (php8.0) |
self | 現在のクラス(メソッドでのみ利用可能) |
*void | なにも返さない |
*static | 最初に呼び出したクラス(遅延静的束縛 php8.0) |
null許容型
型名の先頭に?をつける。
呼び出し元(実引数)で省略は不可
function myFunc(?int $value):void {
var_dump($value);
}
myFunc(300); //int(300)
myFunc(null); //NULL
myFunc(); //エラー
Union型
8.0以降
/function getArea(string|float $base, strign|float $height):float|false
{ ... }
false 擬似型
8.0以降
function getArea(string|float $base, strign|float $height):float|false
{ ... }
引数の参照渡し
仮引数の頭に&を付ける。
function increment(int &$num): int {
$num++;
return $num;
}
$value = 10;
print increment($value); //結果 11
print $value; //結果 11
ただし、参照渡しされた引数を関数の中でunsetしても元の変数には影響しません。この場合、あくまでも引数そのものが破棄されるだけです。
参考記事
リファレンスジェネレーター
yieldという命令を利用することで、つど、その時々の値を返す。
returnも利用可能、最終的な結果を表す getReturn() メソッドを利用する。
function myLang() {
yield 'あいうえお';
yield 'かきくけこ';
yield 'さしすせそ';
return 'end';
}
$lang = myLang();
foreach($lang as $value) {
print $value . '
';
}
// 結果:あいうえお
かきくけこ
さしすせそ
print $lang->getReturn();
// 結果:end
foreach 文で処理する。
ジェネレーター関数の戻り値は、yield命令によって返された値そのものではなく、Generatorオブジェクトです。明示的に型宣言するなら、下記のようになる。
function myLang(): Generator { ~ }
ジェネレーターの中で別のジェネレーターに処理を委譲する。
yield from otherFunctoin();
return 戻り値
return 以降の命令は実行されない。
戻り値がない(return がない)、または空の return; は、null を返したとみなされる。
ただし、戻り値の型宣言にvoidを指定している場合に、return null; とするのは不可。
静的変数 static命令
関数内のローカル変数を維持する。
初回呼び出し時にのみ初期化され、関数の処理が終了しても維持される。
static 変数はリテラルか定数で初期化
式で初期化できない。
static $x = 0: OK
static $x = $y NG
function checkStatic(): int {
static $x = 0;
return ++$x;
}
print checkStatic(); //結果:1
print checkStatic(); //結果:2
unsetの挙動に注意!
static命令の後にunsetしても静的変数の使用を解除し、ローカル変数を使用するという意味になる。静的変数$xに影響しない。
function checkStatic(): void {
static $x = 0;
print "unset前:{$x}";
unset($x);
$x = 10;
print "unset後:{$x}";
}
checkStatic(); //unset前:1 unset後:10
checkStatic(); //unset前:2 unset後:10
global変数の場合も同様
$x = 10;
function checkScope(): int {
global $x;
unset($x);
return ++$x;
}
print checkScope(); //1
print $x; //10
//global変数を破棄する場合
//unset($GLOBAL['X']);
名前付き引数
getArea( 仮引数名: 値 );
可変長引数
function total(float ...$args): float {
$result = 0;
foreach( $args as $arg ) {
$result += $arg;
}
return $result;
}
print total(7, 3, 10); //20
print total(11, -5, 4, 88); //98
可変長引数は、より正しくは「0個以上の引数」。引数なしで total(); の呼び出しでも良い。
確実に一つ以上の引数を要求したい場合、1個目の引数を通常の引数として宣言する。
function total(float $init, float ...$args): float {
$result = $init;
foreach( $args as $arg ) {
$result += $arg;
}
return $result;
}
「…」演算子による引数のアンパック
配列をアンパック(展開)して個々の値として渡すことができる。
function getArea(float $base, float $height): float {
return $base * $height / 2;
}
print getArea(...[10, 5]);
// getArea(10, 5) と同義
//php 7.4以降、配列内でもアンパックできる
$data = ['山田', '田中'];
$member = ['太田', '若林', ...$data, '春日'];
print_r($member);
//結果:Array( [0] => 太田 [1] => 若林 [2] => 山田 [3] => 田中 [4] => 春日)
可変変数
制御構造と言語構造では可変変数の形では使えない。
スーパーグローバルは可変変数として使用できない。
キーワードはいずれも定数、クラス名、 関数名として使用することはできない。
キーワードのリスト(PHP マニュアル)
//include echo などは使えない
$func = 'include';
$func("example.php");
配列で使用する場合は曖昧さを解決する必要がある。
$$a[1] → $a[1] なのか、$$aまでの変数に添字[1]なのか、パーサが知る必要がある。
明示的に記述する → ${$a[1]} ${$a}[1]
クラスのプロパティに、可変プロパティ名でアクセスできる。
可変プロパティ名の解決は呼び出し元のスコープで行われる。
$start = 'b';
$end = 'ar';
echo $foo->{$start . $end} . "\n";
// $foo->bar; と同義
可変関数(Variable Functions)
「$変数名()」の形式で呼び出せる関数。
function getArea(float $base, float $height): float {
return $base * $heihgt / 2;
}
$name = 'getArea';
$area = $name(8, 10);
print "三角形の面積は{$area}です。";
高階関数
関数そのものを引数として渡したり、戻り値として返したりする。
条件に応じてコールバックを差し替えるなど。処理する関数を外から渡す。
function myArrayWalk(array $array, callable $func) : void {
foreach ($array as $key => $value) {
$func($value, $key);
}
}
function showItem(mixed $value, int | string $key) :void {
print "{$key}:{$value}
";
}
$data = ['杉山', '長田', '杉沼', '和田', '土井'];
myArrayWalk($data, 'showItem');
/*
結果:
0:杉山
1:長田
2:杉沼
3:和田
4:土井
*/
無名関数(クロージャー)
呼び出しコードに直接埋め込むことができる。
function( 仮引数, ・・・・) {
// 任意の処理
return 戻り値;
}
変数に代入することもできる。この場合、ブロックの末尾にセミコロン(;)が必要。{ ~ } はブロックの終わりではなく、いわゆる関数リテラルの一部であるから。
$triangle = function($base, $height) { ~ };
親スコープの変数を引き継ぐ場合は、use命令を使用する。既定は値渡しである点に注意。元の変数に変更を加えたい場合は参照渡しにする。
function myArrayWalk(array $array, callable $func) : void {
foreach($array as $key => $value) {
$func($value, $key);
}
}
$data = [100, 50, 10, 5];
$result = 0;
myArrayWalk($data, function($value, $key) use(&$result) { //参照渡し
$result += $value;
});
print "合計値:{$result}"; //結果:合計値:165
アロー関数
PHP 7.4 で追加されました。
アロー関数は 無名関数 と同じ機能をサポートしていますが、 親のスコープで使える変数が常に自動で使える点だけが異なります。(use を使わずに親スコープの変数が使える)
アロー関数の記述より前に変数をセットしておく必要がある。値渡しのため外部変数を変更することは出来ない。
最後にセミコロンが必要。
単一の式しか書けない。
$y = 1;
$fn1 = fn($x) => $x + $y;
// 無名関数で $y を値渡しするのと同じ
$fn2 = function ($x) use ($y) {
return $x + $y;
};
var_export($fn1(3)); // 結果:4
var_export($fn2(3)); // 結果:4
echo $y; // 結果:1