[PHPのはじめ方] Part11: 関数の定義とスコープ、引数と戻り値

PHP

コードを整理し、再利用可能にする魔法 ✨

PHPプログラミングを進めていく上で、関数は避けて通れない重要な要素です。関数を使うことで、同じ処理を何度も書く手間を省き、コードを整理し、読みやすく、そしてメンテナンスしやすくすることができます。

このステップでは、PHPにおける関数の基本である以下の項目について学んでいきましょう!

  • 関数の作り方(定義)
  • 引数を使って関数に情報を渡す方法
  • 関数から結果を受け取る方法(戻り値)
  • 変数がどこで使えるか(スコープ)

1. 関数の定義:自分だけの命令を作ろう! 🛠️

関数を定義するには、function キーワードを使います。基本的な形は次のとおりです。[8][10][24]

<?php
function 関数名(引数1, 引数2, ...) {
  // ここに関数が行う処理を書く
  return 戻り値; // 戻り値がない場合は省略可能
}
?>

関数名は、その関数が何をするのか分かりやすい名前をつけましょう。PHPでは、関数名や変数名にキャメルケース(例:getUserName)を使うのが一般的です。[24]

簡単な例として、挨拶を表示する関数を作ってみましょう。

<?php
// "Hello!" と表示する関数を定義
function sayHello() {
  echo "Hello! 👋<br>";
}

// 関数を呼び出す(実行する)
sayHello(); // 出力: Hello! 👋
sayHello(); // 何度でも呼び出せる! 出力: Hello! 👋
?>

一度定義すれば、関数名() の形で何度でも呼び出すことができます。[8]

2. 引数 (Arguments):関数に情報を渡す 🎁

関数に外部から値(情報)を渡したい場合があります。例えば、挨拶する相手の名前を指定したい場合などです。このような時に使うのが引数(ひきすう)です。[8][25] 引数はカンマ区切りで複数指定できます。[21]

<?php
// 名前を受け取って挨拶する関数
function greet($name) { // $name が引数
  echo "こんにちは、" . htmlspecialchars($name, ENT_QUOTES, 'UTF-8') . "さん! 😊<br>";
}

greet("山田"); // 出力: こんにちは、山田さん! 😊
greet("鈴木"); // 出力: こんにちは、鈴木さん! 😊
?>

💡 ポイント: ユーザーからの入力など、外部の値を扱う際は htmlspecialchars() などを使ってエスケープ処理を行うことが重要です(クロスサイトスクリプティング対策)。

型宣言 (Type Hinting)

PHP 7からは、引数に期待する型を指定できるようになりました。[7][20] これにより、予期しない型の値が渡されるのを防ぎ、コードの信頼性を高めることができます。

<?php
// 引数 $name は文字列(string) であることを期待
function greetWithType(string $name) {
  echo "Hello, " . htmlspecialchars($name, ENT_QUOTES, 'UTF-8') . "! 😉<br>";
}

greetWithType("佐藤"); // OK
// greetWithType(123); // これは TypeError になる
?>

使える型には、int, float, string, bool, array, object などがあります。[20]

デフォルト引数値

引数に値が渡されなかった場合に、自動的に使われる値を設定できます。[7][17][19][25] デフォルト値は、引数リストの後ろの方に定義する必要があります。[17]

<?php
// $message に値が渡されなければ "元気ですか?" を使う
function sendMessage(string $to, string $message = "元気ですか? 🤔") {
  echo htmlspecialchars($to, ENT_QUOTES, 'UTF-8') . "さんへ: " . htmlspecialchars($message, ENT_QUOTES, 'UTF-8') . "<br>";
}

sendMessage("田中", "おはよう!"); // 出力: 田中さんへ: おはよう!
sendMessage("中村");           // 出力: 中村さんへ: 元気ですか? 🤔 (デフォルト値が使われる)
?>

PHP 8.0以降では、名前付き引数 を使って、デフォルト値を持つ引数をスキップすることも可能です。[17]

可変長引数 (Variable-length arguments)

引数の数が決まっていない場合、... (スプレッド演算子) を使って、複数の引数を配列として受け取ることができます (PHP 5.6以降)。[17][25] この機能を使うと、func_num_args(), func_get_arg(), func_get_args() といった関数を使わずに可変長の引数を扱えます。[12][23][24]

<?php
// 受け取った数値をすべて合計する関数
function sum(int ...$numbers): int {
  $total = 0;
  foreach ($numbers as $number) {
    $total += $number;
  }
  return $total;
}

echo sum(1, 2, 3);       // 出力: 6
echo "<br>";
echo sum(10, 20, 30, 40); // 出力: 100
?>

参照渡し (Pass by Reference)

通常、関数に渡された変数の値はコピーされます(値渡し)。関数内で引数の値を変更しても、元の変数には影響しません。しかし、引数の前に & をつけると参照渡しとなり、関数内で引数を変更すると元の変数も変更されます。[7][12][25]

<?php
function addOne(int &$value) { // & をつけて参照渡しにする
  $value++;
}

$num = 5;
addOne($num); // 関数内で $num が変更される
echo $num; // 出力: 6
?>

⚠️ 注意: 参照渡しはコードの挙動を分かりにくくすることがあるため、使用は慎重に検討しましょう。オブジェクトはデフォルトで参照のように振る舞います(実際にはオブジェクト識別子のコピーです)。[12] 参照渡しの引数にもデフォルト値を指定できます。[17]

3. 戻り値 (Return Values):関数からの結果を受け取る ⏎

関数での処理結果を、呼び出し元で使いたい場合があります。その際に使うのが return キーワードです。return の後に記述した値が、関数の戻り値(または返り値)となります。[8][10][21]

<?php
// 二つの数値を足して結果を返す関数
function add(int $a, int $b) {
  $result = $a + $b;
  return $result; // 計算結果を返す
  // return の後のコードは実行されない
  // echo "ここは実行されません";
}

$sumResult = add(5, 3); // 関数の戻り値を変数 $sumResult で受け取る
echo "5 + 3 = " . $sumResult; // 出力: 5 + 3 = 8
echo "<br>";
echo "10 + 7 = " . add(10, 7); // 直接 echo で出力もできる 出力: 10 + 7 = 17
?>

関数内で return が実行されると、その時点で関数の処理は終了し、値が呼び出し元に返されます。return の後に書かれたコードは実行されません。[21]

何も返さない(処理だけを行う)関数の場合は、return; と書くか、return 文自体を省略できます。

戻り値の型宣言 (Return Type Declaration)

PHP 7からは、関数が返す値の型を宣言できるようになりました。[9][20] 引数の型宣言と同様に、コードの信頼性を高めるのに役立ちます。関数の引数リストの後に : 型名 を記述します。

<?php
// 必ず整数(int)を返すことを宣言
function multiply(int $a, int $b): int {
  return $a * $b;
}

// 文字列(string)を返すことを宣言
function getGreeting(string $name): string {
  return "ようこそ、" . htmlspecialchars($name, ENT_QUOTES, 'UTF-8') . "さん! 🎉";
}

$product = multiply(6, 7);
echo $product; // 出力: 42
echo "<br>";
$message = getGreeting("高橋");
echo $message; // 出力: ようこそ、高橋さん! 🎉
?>

何も返さないことを示す `void` 型

PHP 7.1からは、関数が値を返さないことを明確に示す void 型が追加されました。[1][2][6][11] void は戻り値専用の型宣言で、引数には使えません。[2][6]

<?php
// この関数は値を返さないことを宣言
function printMessage(string $message): void {
  echo htmlspecialchars($message, ENT_QUOTES, 'UTF-8');
  // return; はあってもなくても良い (ただし、return で値を返すことはできない) [1][9]
}

printMessage("処理が完了しました。"); // 出力: 処理が完了しました。
// $result = printMessage("..."); // void 型の関数の戻り値を受け取ろうとするとエラーになる (実際には null が返るが、型チェッカーによっては警告される) [2][6][11]
?>

void を宣言すると、関数が副作用(画面出力やDB更新など)を目的としていることが明確になります。[1]

複数の値を返す

PHPの関数は直接的には一つの値しか返せませんが、配列やオブジェクトを使うことで、実質的に複数の値を返すことができます。[21]

<?php
// 配列で複数の計算結果を返す関数
function calculate(int $a, int $b): array {
  return [
    'sum' => $a + $b,
    'difference' => $a - $b,
    'product' => $a * $b
  ];
}

$results = calculate(10, 4);
echo "和: " . $results['sum'] . "<br>";       // 出力: 和: 14
echo "差: " . $results['difference'] . "<br>"; // 出力: 差: 6
echo "積: " . $results['product'] . "<br>";    // 出力: 積: 40

// list() や 配列の分割代入 (PHP 7.1+) を使うと便利
list($s, $d, $p) = array_values(calculate(8, 5)); // PHP 7.0 以前
['sum' => $sumVal, 'difference' => $diffVal, 'product' => $prodVal] = calculate(8, 5); // PHP 7.1+

echo "Sum: {$sumVal}, Diff: {$diffVal}, Prod: {$prodVal}"; // 出力: Sum: 13, Diff: 3, Prod: 40
?>

4. スコープ (Scope):変数が使える範囲 🌍

変数がプログラムのどの範囲で有効か、という概念をスコープと呼びます。PHPには主に以下のスコープがあります。[3][4][5][16][21]

ローカルスコープ (Local Scope)

関数の中で宣言された変数は、デフォルトではその関数の中だけで有効です。これをローカル変数と呼びます。[3][14][16][21] 関数が終わると、その変数は消えてしまいます。[4][12]

<?php
function myFunction() {
  $localVar = "私はローカル変数です"; // 関数内でのみ有効
  echo $localVar . "<br>";
}

myFunction(); // 出力: 私はローカル変数です
// echo $localVar; // エラー!関数の外からはアクセスできない (Undefined variable) [12][18]
?>

グローバルスコープ (Global Scope)

関数の外で宣言された変数はグローバル変数と呼ばれ、スクリプト全体のどこからでも(基本的には)アクセスできますが、関数の中から直接アクセスすることはできません。[3][5][14][16][18]

<?php
$globalVar = "私はグローバル変数です 🌐";

function tryAccessGlobal() {
  // echo $globalVar; // エラー!直接はアクセスできない (Undefined variable) [18]
}

tryAccessGlobal();
echo $globalVar; // 出力: 私はグローバル変数です 🌐 (関数の外からはアクセスできる)
?>

関数内からグローバル変数へのアクセス

関数の中からグローバル変数にアクセスするには、主に2つの方法があります。[4][5]

  1. global キーワード:
    関数内で global $変数名; と宣言すると、その関数内でグローバル変数を使えるようになります。[5][14]
    <?php
    $count = 0;
    
    function incrementCount() {
      global $count; // グローバル変数 $count を使うことを宣言
      $count++;
      echo "カウント: " . $count . "<br>";
    }
    
    incrementCount(); // 出力: カウント: 1
    incrementCount(); // 出力: カウント: 2
    echo "最終カウント: " . $count; // 出力: 最終カウント: 2
    ?>
  2. $GLOBALS スーパーグローバル配列:
    PHPには、すべてのグローバル変数を格納した $GLOBALS という特別な連想配列があります。これを使えば、どこからでもグローバル変数にアクセスできます ($GLOBALS['変数名'] のように)。[4][5]
    <?php
    $appName = "My Awesome App";
    
    function showAppName() {
      echo "アプリ名: " . $GLOBALS['appName'] . "<br>";
      // $GLOBALS['appName'] = "New App Name"; // グローバル変数の書き換えも可能
    }
    
    showAppName(); // 出力: アプリ名: My Awesome App
    ?>

⚠️ 注意: グローバル変数を多用すると、どこで変数が変更されたか追跡しにくくなり、コードが複雑になる原因となります。関数の引数や戻り値を使う方が、より整理されたコードになることが多いです。

静的変数 (Static Variables)

ローカル変数は通常、関数が終了すると値が破棄されますが、static キーワードを使って宣言すると、関数が終了しても値を保持し続けます。[3][5][14][18] 次にその関数が呼び出されたとき、前回の値を維持したまま処理を再開できます。[4] 静的変数の初期化は、関数が最初に呼び出された時に一度だけ行われます。[14]

<?php
function staticCounter() {
  static $counter = 0; // 静的変数として宣言し、初回のみ 0 で初期化
  $counter++;
  echo "静的カウンター: " . $counter . "<br>";
}

staticCounter(); // 出力: 静的カウンター: 1
staticCounter(); // 出力: 静的カウンター: 2 (前回の値 1 を覚えている)
staticCounter(); // 出力: 静的カウンター: 3
?>

静的変数は、特定の関数内でのみ状態を保持したい場合に便利です。

PHP 8.1以降、継承されたメソッド内の静的変数は、親クラスのメソッドと変数を共有するようになりました。[4][5]

まとめ 🎉

今回は、PHPの関数の基本について学びました。

  • function で関数を定義し、同じ処理をまとめる。
  • 引数を使って関数に情報を渡し、処理をカスタマイズする(型宣言やデフォルト値も活用!)。
  • return で関数から戻り値を受け取り、処理結果を利用する(型宣言や void も!)。
  • 変数が使える範囲であるスコープ(ローカル、グローバル、静的)を理解する。

関数を使いこなすことで、あなたのPHPコードはもっと効率的で、読みやすく、再利用しやすいものになります。積極的に関数を活用していきましょう!💪

次のステップでは、さらに便利な「無名関数」や「コールバック関数」について学んでいきます。お楽しみに!

コメント

タイトルとURLをコピーしました