107
126

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PHPのマジックメソッド一覧と使い方まとめ

Last updated at Posted at 2016-10-20

php.netの一覧( http://php.net/manual/ja/language.oop5.magic.php )が見にくかったので自分なりにまとめておく。

  • 2018/05/23 サンプルコードの見直し・追加
  • 2020/02/21 サンプルコードをLaravelを意識したものに見直し

比較的使う子たち

  • __construct
  • __call
  • __callStatic
  • __get
  • __set
  • __toString

__construct( $argments )

クラスがインスタンス化されたときに呼ばれる。
よくある初期化用。依存注入でも使用される。

public function __construct( HogeService $hoge_service ) {
    $this->hoge_service = $hoge_service ;
}
public function __construct( $name = '名無しさん' ) {
    $this->name = $name;
}

__destruct( void )

インスタンスが削除されたときに呼ばれる。
コンストラクタでオープンしたファイルのクローズなどの終了処理を書いておくと便利。

public function __destruct() {
    fclose($this->handle);
}

__call( $name, $argments )

インスタンスに存在しない関数が呼ばれたとき実行される。

public function __call($name, $argments) {
    $name = 'action_'.$name;
    return $name($argments);  //関数action_xxxを実行
}

__callStatic( $name, $argments )

インスタンスに存在しない静的関数が呼ばれたとき実行される。

public static function __callStatic( $name, $argments ) {
    $name = 'scope'.$name;
    static::$name($argments);      //関数scopexxxを実行
}

__get($name)

インスタンスに存在しない変数プロパティが呼び出されたときに実行される。

public static function __get( $name ) {
    return $this->attributes[$name];    //配列attributesのxxxを返す
}

__set($name, $value)

インスタンスに存在しない変数プロパティに代入されたときに実行される。

public static function __set( $name, $value ) {
    $this->attributes[$name] = $value;  //配列attributesのxxxに代入
}

__isset($name)

インスタンスのアクセス不能プロパティに対して isset() あるいは empty() を実行したときに実行される。

public function __isset($name) {
    return isset($this->attributes[$name]); //配列attributesのxxxが存在するかチェック
}

__unset()

インスタンスのアクセス不能プロパティに対して unset() を実行したときに実行される。

public function __unset($name) {
    unset($this->attributes[$name]);      //配列attributesのxxxを削除
}

__sleep()

インスタンスをシリアライズ化時に呼ばれる。
シリアライズに不要なデータや、変換不能なもの(ファイルハンドルなど)を除外するときに使う。
データ授受目的ならjson化した方がいい気もする。
このメソッドではシリアライズ化する対象の変数名文字列の配列を返すようにする。

class Hoge {
    public $file_name;
    private $file_handle;
    private $secret_data;
    
    public function __sleep() {
        return [
            'file_name',
        ];
    }
}

__wakeup()

インスタンスをアンシリアライズ化時に呼ばれる。
アンシリアライズしたデータをからインスタンスに必要なデータを再構築するときに使う。

class Hoge {
    public $file_name;
    private $file_handle;
    private $secret_data;
    
    public function __wakeup() {
        $this->file_handle = fopen($this->file_name, 'r');
    }
}

__toString()

インスタンスがechoなどsting型が要求されえたとき呼ばれる。

class User {
    public function __toString() {
        return "{$this->name} ({$this->age}歳)";
    }
}

$user = new User();
echo $user;
(string) $user;

__invoke( $argments )

インスタンスが関数として呼ばれたときに実行される。

public function __invoke() {
    var_dump($this->text);      //デバッグ用
}

__set_state( array $properties )

インスタンスをvar_exportが呼ばれたときに実行される。

public function __set_state( $properties ) {
    //$propertiesの加工など
    return $properties;
}

__debugInfo()

インスタンスをvar_dumpが呼ばれたときに実行される。

public function __debugInfo() {
    return ['data' => $this->data];
    //$返す値を指定
}

__clone()

インスタンスをクローンするときに呼ばれる。
普通にクローンすると参照渡しになる値(datetimeなど)を別物としてクローンしたい場合時に使う。
最近はイミュータブルなものが増えてきているので表立って使うことは少ないかも。

class A {
   public function __construct() {
      $this->datetime = new DateTime();
   }
}
$a = new A;
$a2 = clone $a;
$a->datetime->modify('tomorrow');
// $a2->datetimeと、$a->datetimeの参照先は同じであるため両方の値が変更されるように見える。
class B extends A {
    public function __clone() {
        $this->datetime = clone $this->datetime;
    }
}
$b = new B;
$b2 = clone $b;
$b->datetime->modify('tomorrow');
// $b2->datetimeと、$b->datetimeの参照先は異なるため$b->datetimeのみ変更される。
107
126
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
107
126

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?