PHP 入門

PHP 型宣言

型宣言(Type Declarations)は、関数に渡されるデータや関数が返すデータの型を強制的に規定する機能です。期待される型を明示することで、PHPは「バックグラウンドで黙々と型変換を行う言語」から、「無効なデータを能動的に拒否する厳格なシステム」へと進化します。これにより、コード実行から数時間後にクラッシュを招くようなバグを、データ入力の段階で効率的にブロックできるようになります。

1. スカラー型宣言

スカラー型宣言を使用すると、関数のパラメータ(引数)に対して期待する型を定義できます。型を指定した場合、strict_types(厳密モード)のディレクティブが有効でない限り、PHPは渡された値を指定された型に自動的に変換しようとします(これは「強制型変換」と呼ばれます)。

現在サポートされている型には、int(整数)、float(浮動小数点数)、string(文字列)、bool(真偽値)、array(配列)、callable(コールバック)、iterable(反復可能オブジェクト)、object(オブジェクト)、および mixed(混合型)があります。

<?php
declare(strict_types=1); 

function calculateArea(int $width, int $height): int {
    return $width * $height;
} 

// 正しい使用例
echo calculateArea(10, 20);  

// 下記のコードは TypeError をスローします。
// 関数は int を期待していますが、string が渡されているためです。
// echo calculateArea("10", 20);

declare(strict_types=1); というディレクティブは極めて重要です。これが記述されていない場合、PHPは「強制型変換」を行い、calculateArea("10", 20) は正常に実行されてしまいます(文字列の "10" が整数 10 に強制変換されるため)。厳密モード(strict mode)は型が完全に一致することを要求し、メンテナンス性の高いプロフェッショナルなコードを書くための基盤となります。

2. 戻り値の型宣言

戻り値の型宣言は、関数が常に特定のデータ型を返すことを保証します。これにより、その関数を呼び出す開発者に対して明確な「契約」を提供でき、関数内部の実装ロジックを読み解かなくても、どのような結果が得られるかを正確に把握できるようになります。

<?php
function getUsername(int $userId): string {
    if ($userId === 1) {
        return "admin";
    }
    return "guest";
}

関数内部のロジックが指定された型を返さなかった場合、PHPは即座に TypeError をスローします。これにより、null や予期しないデータ構造が返されることで発生する、後続処理のクラッシュを未然に防ぐことができます。

3. ヌラブル型

時として、関数には柔軟性が必要です。具体的な値を返すこともあれば、何も返さない(例えば、データベースのクエリが失敗した際に空を返す)こともあります。型宣言の前に疑問符 (?) を付けることで、任意の型をヌラブル型(Nullable)に設定できます。

<?php
function findUserEmail(int $id): ?string {
    $database = [1 => '[email protected]'];
    return $database[$id] ?? null; // 見つからない場合は null を返す
} 

// これは完全に正当な呼び出しです
$email = findUserEmail(99);

4. void 戻り値型

関数が特定の操作(ファイルへの書き込みやデータベースの更新など)を実行するだけで、意味のある値を返す必要がない場合は、void 戻り値型を使用すべきです。これは、その関数の結果を代入式などで利用すべきではないというメッセージを明確に伝えます。

<?php
function logMessage(string $message): void {
    file_put_contents('app.log', $message, FILE_APPEND);
    // ここで明示的な return 文は不要です。
    // また、この関数は値を返してはいけません。
}

5. ユニオン型 (Union Types)

複雑なアプリケーションでは、1つの関数が合理的に複数の異なる型を返す場合があります。ユニオン型(Union Types)では、パイプ記号 (|) を使用して、引数や戻り値が定義された複数の型のいずれかであることを指定できます。

<?php
function formatIdentifier(int|string $id): string {
    return "ID_" . $id;
} 

echo formatIdentifier(101);    // 出力: ID_101
echo formatIdentifier("A-55"); // 出力: ID_A-55

以下のフローチャートは、型宣言が関数の実行プロセスにおいてどのように「ゲートキーパー」としての役割を果たすかを説明しています。

型バリデーションのフロー解析:

  1. 関数呼び出し (Function Call)
  2. パラメータの型チェック (Parameter Type Check)
    • 有効な型 (Valid Type) → 関数本体の実行 (Function Body Execution) へ
    • 無効な型 (Invalid Type) → 型エラーのスロー (Throw TypeError)
  3. 戻り値のチェック (Return Value Check)
    • 有効な戻り値型 (Valid Return Type) → データの返却成功 (Return Data)
    • 无効な戻り値型 (Invalid Return Type) → 型エラーのスロー (Throw TypeError)