同じ処理を何度も書いていると、コードは長くなり、修正のたびにあちこち直すことになります。そんなときに役立つのが「関数」です。この記事では PHP の function キーワードを使った関数の定義方法を、引数・戻り値・デフォルト値・型宣言・可変長引数・名前付き引数まで順を追って解説します。プログラミングを学び始めた方から、関数の書き方を整理し直したい中級者の方までを対象にしています。
目次
なぜ関数にまとめるのか
関数とは、ひとまとまりの処理に名前を付けて、いつでも呼び出せるようにしたものです。たとえば「税込価格を計算する」という処理を関数にしておけば、価格が出てくるたびに同じ計算式を書かなくても、関数名を呼ぶだけで済みます。
関数を使う利点は大きく3つあります。ひとつは、同じ処理を1か所にまとめられるため、修正が必要になったときにその関数だけを直せばよいこと。ふたつめは、処理に名前が付くことでコードの意図が読み取りやすくなること。みっつめは、動作確認をその関数単位で行えることです。まずは実際の定義を見ていきましょう。
関数の基本的な定義
関数は function というキーワードに続けて、関数名・丸かっこ・波かっこを書いて定義します。波かっこの中に、実行したい処理を書きます。定義しただけでは処理は動かず、関数名に丸かっこを付けて「呼び出す」ことで初めて実行されます。
<?php
// あいさつを表示する関数を定義する
function greet() {
echo "こんにちは、PHP!\n";
}
// 関数を呼び出す(ここで処理が実行される)
greet(); // こんにちは、PHP!
greet(); // 何度でも呼び出せる
関数名は英字またはアンダースコアで始め、英数字とアンダースコアが使えます。大文字・小文字は関数名では区別されませんが、読みやすさのために getUserName や get_user_name のように、意味の分かる名前を一貫したスタイルで付けることをおすすめします。
引数で値を受け取り、return で返す
関数の丸かっこの中に変数を書くと、呼び出すときに値を渡せます。この受け渡しの窓口になる変数を「引数(ひきすう)」と呼びます。そして、関数の処理結果を呼び出し元に返すには return を使います。return が実行されるとその時点で関数は終了し、書かれた値が呼び出し元に戻ります。
<?php
// 2つの数値を受け取り、その合計を返す
function add($a, $b) {
return $a + $b;
}
$result = add(3, 5); // 戻り値を変数に受け取る
echo $result; // 8
// 戻り値をそのまま使うこともできる
echo add(10, 20); // 30
return を書かない関数、あるいは値を付けずに return; だけを書いた関数は、null を返します。「値を返す関数」と「表示や処理だけを行い値を返さない関数」を意識して使い分けると、コードの見通しがよくなります。
デフォルト値で引数を省略できるようにする
引数に = で初期値を指定しておくと、呼び出し時にその引数を省略できます。省略された場合は初期値(デフォルト値)が使われます。よく使う設定値をあらかじめ決めておき、必要なときだけ上書きする、といった使い方に便利です。
<?php
// $taxRate を省略すると 0.1(10%)が使われる
function withTax($price, $taxRate = 0.1) {
return (int) ($price * (1 + $taxRate));
}
echo withTax(1000); // 1100(デフォルトの10%)
echo "\n";
echo withTax(1000, 0.08); // 1080(8%を指定)
デフォルト値を持つ引数は後ろに置く
デフォルト値を付けた引数は、原則として引数リストの末尾にまとめます。次のように、デフォルト値のない引数がデフォルト値付き引数より後ろにあると、途中の引数だけを省略できず、期待どおりに動きません。
<?php
// 悪い例:デフォルト値付きの引数が前にある
function makeLabel($prefix = "No.", $number) {
return $prefix . $number;
}
// $prefix だけ省略して $number を渡す、ということはできない
// makeLabel(5); のように呼ぶとエラーになる
// 良い例:省略したい引数を後ろに置く
function makeLabelGood($number, $prefix = "No.") {
return $prefix . $number;
}
echo makeLabelGood(5); // No.5
echo "\n";
echo makeLabelGood(5, "第"); // 第5
なお、PHP 8.0 以降では、後述する名前付き引数を使えば、途中の引数だけをデフォルトのまま残して指定することもできます。それでも、引数の並び順は「必須のものを前、省略できるものを後ろ」にしておくのが基本です。
型宣言で引数と戻り値の型を明示する
引数の前に型名を書くと、その引数に渡せる値の型を制限できます。また、引数リストの丸かっこのあとに : 型名 と書くと、戻り値の型を宣言できます。型を明示しておくと、想定外の値が渡されたときにエラーで気づけるうえ、コードを読む人にも「何を渡し、何が返るのか」が伝わります。
<?php
// 引数は int、戻り値も int と宣言する
function square(int $number): int {
return $number * $number;
}
echo square(4); // 16
// 値を返さない関数は戻り値の型に void を指定できる
function logMessage(string $message): void {
echo "[LOG] " . $message . "\n";
}
logMessage("処理を開始しました");
主な型宣言には次のようなものがあります。用途に合わせて使い分けてください。
| 型宣言 | 意味 |
|---|---|
int | 整数 |
float | 小数(浮動小数点数) |
string | 文字列 |
bool | 真偽値(true / false) |
array | 配列 |
?int など | その型または null を許容する(nullable) |
void | 戻り値がない(return で値を返さない)※戻り値の型のみ |
ファイルの先頭に declare(strict_types=1); と書くと、型のチェックが厳密になります。指定しない場合、たとえば int の引数に文字列 "4" を渡すと自動的に数値へ変換されますが、厳密モードでは型が一致しないとエラーになります。意図しない変換を防ぎたいときに有効です。
可変長引数で個数の決まらない値を受け取る
引数の前に ...(ドット3つ)を付けると、渡された値をすべて1つの配列としてまとめて受け取れます。これを可変長引数と呼びます。合計や連結のように、いくつ値が渡されるか事前に決まらない処理で役立ちます。
<?php
// 渡された数値を $numbers という配列でまとめて受け取る
function sumAll(...$numbers) {
$total = 0;
foreach ($numbers as $n) {
$total += $n;
}
return $total;
}
echo sumAll(1, 2, 3); // 6
echo "\n";
echo sumAll(10, 20, 30, 40); // 100
逆に、すでに配列になっている値を、個々の引数として関数に渡したいときも ... が使えます。この「配列を展開して渡す」書き方をスプレッド構文と呼びます。
<?php
function add($a, $b, $c) {
return $a + $b + $c;
}
$values = [1, 2, 3];
// 配列を展開して、それぞれの引数として渡す
echo add(...$values); // 6
名前付き引数で引数を指定する(PHP 8)
PHP 8.0 からは、引数を「渡す順番」ではなく「引数名」で指定できるようになりました。これを名前付き引数と呼びます。引数名: 値 の形で渡すため、渡したい引数だけを選んで指定でき、残りはデフォルト値のまま使えます。引数の多い関数でも、どの値が何を意味するのかがひと目で分かります。
<?php
function buildUrl(string $path, bool $ssl = true, int $port = 80): string {
$scheme = $ssl ? "https" : "http";
return "{$scheme}://example.com:{$port}{$path}";
}
// $ssl はデフォルトのまま、$port だけを名前で指定する
echo buildUrl("/blog", port: 8080);
// https://example.com:8080/blog
順番で渡す通常の引数(位置引数)と名前付き引数は組み合わせられますが、その場合は位置引数を先に、名前付き引数を後に書く必要があります。
値渡しと参照渡しの違い
PHP の引数は通常「値渡し」です。関数には値のコピーが渡されるため、関数の中で引数を書き換えても、呼び出し元の変数には影響しません。一方、引数名の前に & を付けると「参照渡し」になり、関数内での変更が呼び出し元の変数にもそのまま反映されます。
<?php
// 値渡し:呼び出し元は変わらない
function addOne($n) {
$n = $n + 1;
}
$x = 10;
addOne($x);
echo $x; // 10(変化なし)
echo "\n";
// 参照渡し:& を付けると呼び出し元も変わる
function addOneRef(&$n) {
$n = $n + 1;
}
$y = 10;
addOneRef($y);
echo $y; // 11(変化する)
参照渡しは呼び出し元の値を直接書き換えられて便利に見えますが、どこで値が変わったのかが追いにくくなり、思わぬ不具合の原因になりがちです。基本は値渡しにして、処理結果は return で返す。参照渡しは、複数の値をまとめて更新したいなど、明確な理由があるときだけに絞るのがおすすめです。
まとめ
PHP の関数は function 関数名() { 処理 } で定義し、丸かっこを付けて呼び出します。引数で値を受け取り、return で結果を返すのが基本の形です。引数には = でデフォルト値を設定でき、省略できる引数は末尾に置くのがルールでした。
さらに、引数と戻り値には int や string といった型を宣言でき、... による可変長引数で個数の決まらない値も受け取れます。PHP 8 の名前付き引数を使えば、必要な引数だけを名前で指定できます。引数は通常コピーが渡される値渡しで、& を付けると参照渡しになる点も押さえておきましょう。まずは基本の定義から書き始め、少しずつこれらの機能を取り入れてみてください。