【PHP8.x】__constructメソッドの使い方

__constructメソッドの使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

__construct メソッドは RequestParseBodyException クラスの新しいインスタンスを初期化するメソッドです。これは、HTTPリクエストのボディ(本文)の解析中に問題が発生したことを示す RequestParseBodyException オブジェクトを生成する際に自動的に呼び出される特別なメソッドであり、オブジェクトの初期設定を行います。

この例外は、HTTPリクエストボディの解析エラー、例えばクライアントから送信されたJSONやフォームデータの形式が不正であるなど、Webアプリケーションが受け取ったデータの構造に問題がある場合に利用されます。

コンストラクタは、エラーメッセージ($message)、エラーを識別する数値コード($code)、そしてもしこの例外が別の例外によって引き起こされた場合にその元の例外($previous)を受け取り、例外オブジェクトに詳細な情報を持たせることが可能です。

システムエンジニアを目指す方にとって、この例外はクライアントからのデータ入力検証とエラーハンドリングの重要性を示します。この例外が発生した場合は、送信されたデータ形式の妥当性や、サーバー側の解析処理に不備がないかを確認し、適切に対応することが求められます。例えば、不正な形式のデータが送信された場合は、クライアントに具体的なエラーメッセージを返して修正を促すなどの処理が考えられます。

構文(syntax)

1public function __construct(string $message = "", int $code = 0, ?Throwable $previous = null)

引数(parameters)

string $message = '', int $code = 0, ?Throwable $previous = null

  • string $message: エラーメッセージを指定する文字列
  • int $code: エラーコードを指定する整数
  • ?Throwable $previous: 前の例外(エラー)を指定するThrowableオブジェクト、またはnull

戻り値(return)

戻り値なし

戻り値はありません

サンプルコード

PHP 8 コンストラクタプロパティ昇格でクラスを定義する

1<?php
2
3/**
4 * ユーザー情報を表すクラス
5 */
6class User
7{
8    // PHP 8.0から導入された「コンストラクタのプロパティ昇格 (Constructor Property Promotion)」機能。
9    // コンストラクタの引数に `public` や `private` などの可視性を付けることで、
10    // プロパティの宣言と、コンストラクタ内での代入 (`$this->name = $name;`) を同時に行うことができます。
11    // これにより、コードがより簡潔になります。
12    public function __construct(
13        public readonly int $id,
14        public readonly string $name,
15        public readonly string $email,
16    ) {
17        // この中身は空でも、プロパティの初期化は自動的に行われます。
18    }
19}
20
21// コンストラクタの引数に値を渡して、インスタンスを生成します。
22$user = new User(1, 'Taro Yamada', 'taro@example.com');
23
24// 昇格されたプロパティにアクセスして値を表示します。
25// `readonly` が指定されているため、これらのプロパティは変更できません。
26echo "ID: " . $user->id . PHP_EOL;
27echo "Name: " . $user->name . PHP_EOL;
28echo "Email: " . $user->email . PHP_EOL;
29
30?>

このPHPサンプルコードは、Userクラスのインスタンスを生成し、そのプロパティを表示するものです。ここで重要なのは、PHP 8.0から導入された「コンストラクタのプロパティ昇格」という機能です。

__constructメソッドは、クラスから新しいインスタンスが生成される際に自動的に呼び出される特別なメソッド(コンストラクタ)です。このサンプルコードでは、コンストラクタの引数にpublic readonlyというキーワードが付与されています。これがプロパティ昇格の構文です。

通常、クラスのプロパティはクラスの冒頭で宣言し、コンストラクタ内で引数から受け取った値を代入する必要がありました。しかし、プロパティ昇格機能を使うと、引数に可視性(publicなど)を付けるだけで、プロパティの宣言と値の代入を同時に行うことができます。これにより、クラス定義が非常に簡潔になります。

また、readonlyキーワードは、プロパティが一度初期化された後に値を変更できなくするものです。これにより、データの不変性が保証され、より安全なコードを書くことができます。

このコンストラクタは、インスタンスを初期化するための値(ID、名前、メールアドレス)を引数として受け取ります。コンストラクタ自体は特定の値を返す役割を持たないため、戻り値はありません。

このコードで利用されている「コンストラクタのプロパティ昇格」は、PHP 8.0以降の機能です。古いバージョンのPHPではエラーとなるため、実行環境の確認が必要です。この構文は、コンストラクタの引数にpublicなどの可視性修飾子を付けると、プロパティの宣言と初期化のコードを省略できる便利な機能ですが、__constructメソッドでのみ利用可能です。また、readonly(PHP 8.1以降)が指定されたプロパティは、一度値が設定されると変更できなくなります。例えば、インスタンス生成後に$user->id = 2;のように値を再代入しようとするとエラーになります。これは意図しないデータの書き換えを防ぎ、プログラムの安全性を高めるための重要な仕組みです。

PHPカスタム例外でparent::__construct()する

1<?php
2
3/**
4 * リクエストボディの解析に関連するカスタム例外クラスの例。
5 * PHPの標準的なExceptionクラスを継承し、例外処理の基本を示します。
6 */
7class MyRequestParseBodyException extends Exception
8{
9    /**
10     * コンストラクタ。
11     * 親クラス (Exception) のコンストラクタと同じ引数を受け取ります。
12     *
13     * @param string     $message  例外メッセージ。デフォルトは空文字列。
14     * @param int        $code     例外コード。デフォルトは0。
15     * @param ?Throwable $previous 以前に発生した例外(例外チェイニング用)。デフォルトはnull。
16     */
17    public function __construct(string $message = '', int $code = 0, ?Throwable $previous = null)
18    {
19        // 親クラス (Exception) のコンストラクタを呼び出します。
20        // これにより、メッセージ、コード、前の例外が適切に設定されます。
21        // PHPのコンストラクタでは、通常、このように親クラスのコンストラクタを呼び出すことで、
22        // 親クラスの初期化処理を確実に実行します。
23        parent::__construct($message, $code, $previous);
24
25        // 必要であれば、ここでカスタムの初期化処理を追加できます。
26        // 例: エラーログの記録、特定のプロパティの設定など。
27        // error_log("MyRequestParseBodyException が発生しました: " . $message);
28    }
29
30    /**
31     * カスタム例外に固有のメソッドを追加することも可能です。
32     * このメソッドは、例外の種類を識別するための追加情報を提供します。
33     *
34     * @return string 例外のタイプを示す文字列。
35     */
36    public function getExceptionType(): string
37    {
38        return "PARSE_BODY_ERROR";
39    }
40}
41
42// 以下は、MyRequestParseBodyException クラスの使用例です。
43
44try {
45    // リクエストボディの解析中にエラーが発生したと仮定し、カスタム例外をスローします。
46    // メッセージとエラーコードを指定しています。
47    throw new MyRequestParseBodyException("JSON形式のリクエストボディの解析に失敗しました。", 4001);
48
49} catch (MyRequestParseBodyException $e) {
50    // MyRequestParseBodyException が捕捉されます。
51    echo "--- カスタム例外を捕捉しました ---" . PHP_EOL;
52    echo "例外メッセージ: " . $e->getMessage() . PHP_EOL;    // 親クラスから継承したメソッド
53    echo "例外コード: " . $e->getCode() . PHP_EOL;          // 親クラスから継承したメソッド
54    echo "発生ファイル: " . $e->getFile() . PHP_EOL;
55    echo "発生行: " . $e->getLine() . PHP_EOL;
56    echo "例外タイプ: " . $e->getExceptionType() . PHP_EOL; // カスタムメソッド
57
58} catch (Exception $e) {
59    // その他の一般的な例外を捕捉する場合
60    echo "--- 一般的な例外を捕捉しました ---" . PHP_EOL;
61    echo "メッセージ: " . $e->getMessage() . PHP_EOL;
62}
63
64echo PHP_EOL;
65
66// 例外チェイニングの例: 別の例外が原因でMyRequestParseBodyExceptionが発生した場合
67try {
68    // 最初に発生した内部的なエラー
69    try {
70        // 例えば、データベース接続エラーなど
71        throw new PDOException("データベース接続に失敗しました。");
72    } catch (PDOException $pdoException) {
73        // その内部的なエラーを原因として、MyRequestParseBodyException をスローします。
74        // $pdoException を $previous 引数として渡すことで、例外が連鎖します。
75        throw new MyRequestParseBodyException(
76            "システム内部エラーによりリクエスト処理に失敗しました。",
77            5000,
78            $pdoException // 以前の例外を渡す
79        );
80    }
81} catch (MyRequestParseBodyException $e) {
82    echo "--- 例外チェイニングの例を捕捉しました ---" . PHP_EOL;
83    echo "現在の例外メッセージ: " . $e->getMessage() . PHP_EOL;
84    echo "現在の例外コード: " . $e->getCode() . PHP_EOL;
85
86    $previous = $e->getPrevious(); // チェーンされた前の例外を取得
87    if ($previous !== null) {
88        echo "前の例外メッセージ: " . $previous->getMessage() . PHP_EOL;
89        echo "前の例外クラス: " . get_class($previous) . PHP_EOL;
90    }
91}
92
93?>

RequestParseBodyExceptionクラスの__constructメソッドは、このクラスのインスタンスがnewキーワードで生成される際に自動的に呼び出される、初期化のための特別なメソッド(コンストラクタ)です。

このコンストラクタは、例外オブジェクトが持つべき情報を設定する役割を担います。引数として、エラー内容を示す文字列$message、エラー種別を識別するための数値$code、そして直前に発生した例外を格納する$previousの3つを受け取ります。$previous引数は、あるエラーが別のエラーを引き起こした際に原因をたどる「例外チェイニング」という仕組みで利用されます。

サンプルコードで示されているように、子クラスでコンストラクタを定義する際は、parent::__construct()という記述で親クラスのコンストラクタを呼び出すのが一般的です。PHPにおけるparentは親クラスを指し、この記述によって、Exceptionクラスが持つ基本的な初期化処理(メッセージやコードの設定など)を確実に実行できます。コンストラクタはオブジェクトを初期化することが目的のため、戻り値はありません。

このサンプルコードでは、Exceptionクラスを継承して独自の例外クラスを作成しています。子クラスでコンストラクタ(__construct)を定義した場合、親クラスのコンストラクタは自動で呼ばれないため、parent::__construct()を明示的に呼び出すことが非常に重要です。これを忘れると、例外メッセージやコードが正しく設定されず、getMessage()などのメソッドが期待通りに動作しなくなります。エラーの種類ごとに独自の例外クラスを作ることで、catchブロックで特定のエラーだけを捕捉しやすくなり、プログラムの堅牢性が向上します。最後の$previous引数は、エラーの根本原因を特定するための例外チェイニングで使われ、デバッグに役立ちます。

【PHP8.x】__constructメソッドの使い方 | いっしー@Webエンジニア