PHPのマジックメソッド

マジックメソッドとは、オブジェクトに対して特定の操作が行われた時に自動的に呼ばれる特殊なメソッドです。マジックメソッドを使うと特定の処理に対するオブジェクトの挙動を変更することができるため、PHPでクラスを扱う上でのメリットの一つと言えます。マジックメソッドは、必要なければ省略することもできます。

__get

__getは、定義されていないプロパティやアクセス権のないプロパティを取得しようとした際に呼ばれます。第1引数に取得しようとしたプロパティ名が渡されます。必要に応じて、returnで戻り値を返すことができます。

PHP

<?php
class Foo
{
  public function __get($name)
  {
    echo '__get(' . $name . ') was called.', PHP_EOL;
    return 'hoge';
  }
}
$foo = new Foo();
echo $foo->hoge;
/* 出力:
__get(hoge) was called.
hoge
*/
?>

__set

__setは、定義されていないプロパティやアクセス権のないプロパティに値を代入しようとした際に呼ばれます。第1引数にプロパティ名、第2引数に代入しようとした値が渡されます。

PHP

<?php
class Foo
{
  public function __set($name, $value)
  {
    echo '__set(' . $name . ', ' . $value . ') was called.', PHP_EOL;
  }
}
$foo = new Foo();
$foo->hoge = 100; // 出力:__set(hoge, 100) was called.
?>

__isset

__issetは、定義されていないプロパティやアクセス権のないプロパティに対して、isset()やempty()が実行された際に呼ばれます。第1引数にプロパティ名が渡されます。必要に応じて、returnで論理値を返すことができます。

PHP

<?php
class Foo
{
  public function __isset($name)
  {
    echo '__isset(' . $name . ') was called.', PHP_EOL;
    return false;
  }
}
$foo = new Foo();
var_dump(isset($foo->hoge));
/* 出力:
__isset(hoge) was called.
bool(false)
*/
?>

__unset

__unsetは、定義されていないプロパティやアクセス権のないプロパティに対して、unset()が実行された際に呼ばれます。第1引数にプロパティ名が渡されます。

PHP

<?php
class Foo
{
  public function __unset($name)
  {
    echo '__unset(' . $name . ') was called.', PHP_EOL;
  }
}
$foo = new Foo();
unset($foo->hoge); // 出力:__unset(hoge) was called.
?>

__call

__callは、定義されていないメソッドやアクセス権のないメソッドが呼ばれた際に呼ばれます。第1引数に呼び出そうとしたメソッド名、第2引数に渡そうとした引数が配列で渡されます。必要に応じて、returnで戻り値を返すことができます。

PHP

<?php
class Foo
{
  public function __call($name, $arguments)
  {
    echo '__call(' . $name . ', array(' . implode(', ', $arguments) . ')) was called.', PHP_EOL;
    return false;
  }
}
$foo = new Foo();
$hoge = $foo->hoge(0, 1, 2);
var_dump($hoge);
/* 出力:
__call(hoge, array(0, 1, 2)) was called.
bool(false)
*/
?>

__callStatic

__callStaticは、定義されていないstaticメソッドやアクセス権のないstaticメソッドが呼ばれた際に呼ばれます。第1引数に呼び出そうとしたstaticメソッド名、第2引数に渡そうとした引数が配列で渡されます。必要に応じて、returnで戻り値を返すことができます。

PHP

<?php
class Foo
{
  public static function __callStatic($name, $arguments)
  {
    echo '__callStatic(' . $name . ', array(' . implode(', ', $arguments) . ')) was called.', PHP_EOL;
    return false;
  }
}
$hoge = Foo::hoge(0, 1, 2);
var_dump($hoge);
/* 出力:
__callStatic(hoge, array(0, 1, 2)) was called.
bool(false)
*/
?>

__construct

__constructは、コンストラクタとも呼ばれ、クラスがインスタンス化される際に実行されます。多くの場合、コンストラクタで初期化に必要な処理を行います。

PHP

<?php
class Foo
{
  public function __construct()
  {
    echo '__construct() was called.', PHP_EOL;
  }
}
$foo = new Foo(); // 出力:__construct() was called.
?>

__destruct

__destructは、デストラクタとも呼ばれ、インスタンスが破棄される際に実行されます。参照を明示的に破棄してリファレンスカウントを0にしなかった場合は、PHPプログラムの実行終了時にデストラクタが実行されます。

PHP

<?php
class Foo
{
  public function __destruct()
  {
    echo '__destruct() was called.', PHP_EOL;
  }
}
$foo = new Foo();
unset($foo); // 出力:__destruct() was called.
?>

__sleep

__sleepは、オブジェクトをserialize()関数に渡した際に呼ばれます。__sleep()は、戻り値として配列を返すことが前提となっており、返さなかった場合はE_NOTICEが発生します。

PHP

<?php
class Foo
{
  public function __sleep()
  {
    echo '__sleep() was called.', PHP_EOL;
    return array();
  }
}
$foo = new Foo();
$hoge = serialize($foo); // 出力:__sleep() was called.
?>

__wakeup

__wakeupは、文字列からオブジェクトをunserialize()する際に呼ばれます。

PHP

<?php
class Foo
{
  public function __wakeup()
  {
    echo '__wakeup() was called.', PHP_EOL;
  }
}
$foo = new Foo();
$hoge = serialize($foo);
$bar = unserialize($hoge); // 出力:__wakeup() was called.
?>

__toString

__toStringは、オブジェクトを文字列にキャストした際に呼ばれます。戻り値として文字列を返す必要があります。

PHP

<?php
class Foo
{
  public function __toString()
  {
    echo '__toString() was called.', PHP_EOL;
    return 'Foo';
  }
}
$foo = new Foo();
echo $foo, PHP_EOL;
/* 出力:
__toString() was called.
Foo
*/
?>

__invoke

__invokeは、オブジェクトを関数として実行しようとした際に呼ばれます。PHP5.3以降で利用可能です。

PHP

<?php
class Foo
{
  public function __invoke()
  {
    echo '__invoke() was called.', PHP_EOL;
  }
}
$foo = new Foo();
$foo(); // 出力:__invoke() was called.
?>

__set_state

__set_stateは、var_export()したオブジェクトを復元する際に呼ばれます。引数でエクスポートされたプロパティが連想配列で渡されます。

PHP

<?php
class Foo
{
  public $name;
  public $num;
  public static function __set_state($array)
  {
    echo '__set_state(array(' . implode(', ', $array) . ')) was called.', PHP_EOL;
    $obj = new self();
    foreach ($array as $key => $value) {
      $obj->$key = $value;
    }
    return $obj;
  }
}
$foo = new Foo();
$foo->name = 'Foo';
$foo->num = 1;
$hoge = var_export($foo, true);
eval('$bar = ' . $hoge . ';');
var_dump($bar);
/* 出力:
__set_state(array(Foo, 1)) was called.
object(Foo)#2 (2) {
  ["name"]=>
  string(3) "Foo"
  ["num"]=>
  int(1)
}
*/
?>

__clone

__cloneは、cloneキーワードによりオブジェクトの複製が作成された際にクローン側で呼ばれます。

PHP

<?php
class Foo
{
  public function __clone()
  {
    echo '__clone() was called.', PHP_EOL;
  }
}
$foo = new Foo();
$fooClone = clone $foo; // 出力:__clone() was called.
?>