[PHP] マジックメソッド - クラスオブジェクトについての処理

クラスのオブジェクトに関するマジックメソッドについて3つほどまとめます。

__toStringメソッド

__toStringメソッドは、クラスのオブジェクトを文字列として出力しようとした際に呼び出されるマジックメソッドです。

通常クラスのオブジェクトは、文字列として出力しようとしてもconvertエラーとなってしまい出力できません。

class Test {
    private string $name;

    public function __construct(string $name) {
        $this->name = $name;
    }
}

$test = new Test("Hoge");

echo "name=", $test, "\n";
$ php test_magic-method.php
name=
Fatal error: Uncaught Error: Object of class Test could not be converted
    to string in .¥test_magic-method.php:101
Stack trace:
#0 {main}
  thrown in .\test_magic-method.php on line 101

これを解決するのが__toStringメソッドです。

マジックメソッドのシグネチャ

1. __toStringメソッドのシグネチャ
アクセス修飾子 public
メソッド名 __toString
戻り値 string

[実装例]クラスオブジェクトの文字列変換

冒頭のコードに__toStringメソッドを実装して、文字列に変換した場合の出力を指定します。

コード

class Test {
    private string $name;

    public function __construct(string $name) {
        $this->name = $name;
    }

    public function __toString() {
        return $this->name;
    }
}

$test = new Test("Hoge");

echo "name=", $test, "\n";

実行結果

$ php test_magic-method.php
name=Hoge

__invokeメソッド

__invokeメソッドは、クラスオブジェクトを関数として実行したときに呼び出されるマジックメソッドです。

引数は__invokeメソッドの定義で任意に指定します。この時、実行側で引数の型と数を合わせないとエラーになります。

マジックメソッドのシグネチャ

2. __invokeメソッドのシグネチャ
アクセス修飾子 public
メソッド名 __invoke
引数 任意(自由に定義できる)
戻り値 mixed

[実装例]__invokeメソッドで数値の加算

コード

class Test {
    private int $value;

    public function __construct(int $value) {
        $this->value = $value;
    }

    public function __invoke(int $addValue) {
        return $this->value + $addValue;
    }
}

$test = new Test(3);

echo "addValue=", $test(5), "\n";

実行結果

$ php test_magic-method.php
addValue=8

__cloneメソッド

__cloneメソッドは、クラスオブジェクトに対してclone関数を実行したときに呼び出されるメソッドです。

cloneメソッドでオブジェクトをコピーを作成する際、オブジェクトの属性に関しては、その参照がコピーされます。

以下のコードではItemオブジェクトを保持したTestクラスのオブジェクトをコピーし、コピーした先のオブジェクトに含まれるItemクラスのオブジェクトを更新しています。

class Item {
    public int $id;
    public string $name;
    public function __construct(int $id, string $name) {
        $this->id = $id;
        $this->name = $name;
    }
}

class Test {
    public Item $item;

    public function __construct(Item $item) {
        $this->item = $item;
    }
}

$item = new Item(1, "Hoge");
$test1 = new Test($item);

$test2 = clone $test1;
var_dump($test1->item === $test2->item);

$test2->item->name = "Fuga";

echo "test1->item->name=", $test1->item->name, "\n";
echo "test2->item->name=", $test2->item->name, "\n";

しかし実行してみると、Itemクラスオブジェクトが同じ参照をさしているため、どちらのオブジェクトも同じように更新されてしまいます。

$ php test_magic-method.php
bool(true)
test1->item->name=Fuga
test2->item->name=Fuga

この時、Itemクラスのオブジェクトを別のオブジェクトとしてcloneしたい場合は、__cloneメソッドを使うと実現できます。

マジックメソッドのシグネチャ

3. __cloneメソッドのシグネチャ
アクセス修飾子 public
メソッド名 __clone
引数 なし
戻り値 void

[実装例]__cloneメソッドでオブジェクトに含まれる属性のcloneを生成する

コード

class Item {
    public int $id;
    public string $name;
    public function __construct(int $id, string $name) {
        $this->id = $id;
        $this->name = $name;
    }
}

class Test {
    public Item $item;

    public function __construct(Item $item) {
        $this->item = $item;
    }

    public function __clone() {
        $this->item = clone $this->item;
    }
}

$item = new Item(1, "Hoge");
$test1 = new Test($item);

$test2 = clone $test1;
var_dump($test1->item === $test2->item);

$test2->item->name = "Fuga";

echo "test1->item->name=", $test1->item->name, "\n";
echo "test2->item->name=", $test2->item->name, "\n";

実行結果

$ php test_magic-method.php
bool(false)
test1->item->name=Hoge
test2->item->name=Fuga

__debugInfoメソッド

__debugInfoメソッドは、クラスオブジェクトに対してvar_dump関数を実行したときに呼び出されるマジックメソッドです。任意の配列を返してやることで、var_dumpによるデバッグ情報をカスタマイズすることが出来ます。

マジックメソッドのシグネチャ

4. __debugInfoメソッドのシグネチャ
アクセス修飾子 public
メソッド名 __debugInfo
引数 なし
戻り値 array

[実装例]デバッグ情報をカスタマイズする

以下の例では、ID、名前、年齢を保持したMemberクラスのデバッグ情報として、IDと名前のみを表示するようにカスタマイズしています。

コード

class Member {
    private int $id;
    private string $name;
    private int $age;

    public function __construct(int $id, string $name, int $age) {
        $this->id = $id;
        $this->name = $name;
        $this->age = $age;
    }

    public function __debugInfo() {
        return [
            'id' => $this->id,
            'name' => $this->name,
        ];
    }
}

$member = new Member(1, 'Hoge', 30);

var_dump($member);

実行結果

$ php test_magic-method.php
object(Member)#1 (2) {
  ["id"]=>
  int(1)
  ["name"]=>
  string(4) "Hoge"
}

コメント

このブログの人気の投稿

docker-compose up で proxyconnect tcp: dial tcp: lookup proxy.example.com: no such host

docker-compose で起動したweb、MySQLに接続できない事象

【PHP】PHP_CodeSnifferを使う(コーディングルールのカスタマイズ)