1
1

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 2020-01-02

マジックメソッド

  • インスタンスがある特定の条件になったときに、明示的にcallしなくても暗黙的にcallされるメソッド。
  • 名前の先頭2文字がアンダースコア(__)になっている。
  • 必ずpublicで定義する必要あり。
  • マジックメソッドの引数は参照渡しはできない。
<?php
class SampleClass
{
    private $values = array();

    //getter
    public function __get($name)
    {
        echo "__get: $name", PHP_EOL;
    }

    //setter
    public function __set($name, $value)
    {
        echo "__set: $name setted to $value", PHP_EOL;
        $this->values[$name] = $value;
    }

    //アクセス不能なプロパティにisset()を実行
    public function __isset($name)
    {
        echo "__isset: $name", PHP_EOL;
        return isset($this->values[$name]);
    }

    //アクセス不能なプロパティにunset()を実行
    public function __unset($name)
    {
        echo "__unset: $name", PHP_EOL;
        unset($this->values[$name]);
    }

    //アクセス不能なメソッドを呼び出す
    public function __call($name, $args)
    {
        echo "__call: $name", PHP_EOL;
    }

    public function __invoke($name)
    {
        echo "__invoke: $name", PHP_EOL;
    }
}

$obj = new SampleClass;

//アクセス不能プロパティに10を代入する
//__set()が呼ばれる
$obj->foo = 10;

//アクセス不能プロパティの$fooを取得する
//__get()が呼ばれる
$obj->foo;

var_dump(isset($obj->foo)); //true

//アクセス不能なプロパティに対してunset()を実行
//__unset()が呼ばれる
unset($obj->foo);
var_dump(isset($obj->foo)); //false

//アクセス不能なメソッドを呼び出す
//___call()が呼ばれる
$obj->bar();

遅延静的束縛(Late Static Bindings)

  • 継承されたクラスのメソッドなどを親クラスで解決する機能
  • 直近の 非転送コール のクラス名を保存します。
  • staticキーワードをつける。
  • 普通にインスタンスからアロー演算子でアクセスする時と同じような挙動になる。

####非転送コール

  • self:: や parent::、static:: による静的なコール

####転送コール

  • クラス名::といったクラス名を明示したコール

####self::の制限

self:: あるいは __CLASS__による現在のクラスへの静的参照は、 そのメソッドが属するクラス (つまり、 その>メソッドが定義されているクラス) に解決されます。

<?php
class Foo
{
    public function helloGateway()
    {
        self::hello();
    }

    public static function hello()
    {
        echo __CLASS__, ' hello!', PHP_EOL;
    }
}

class Bar extends Foo
{
    public static function hello()
    {
        echo __CLASS__, ' hello!', PHP_EOL;
    }
}

$bar = new Bar();
//Fooを継承しhello()メソッドをオーバーライドしたBarクラスでも
//自分自身の親が持つメソッドを参照することができない。
$bar->helloGateway(); //Foo hello!

staticキーワードを用いることで、実行時に最初にコールされたクラスを参照する。

<?php
class Foo
{
    public function helloGateway()
    {
       static::hello(); //遅延静的束縛
    }

}
--------------------
$bar = new Bar();
$bar->helloGateway(); //Bar hello!

参考

公式ドキュメント
https://www.php.net/manual/ja/language.oop5.magic.php
https://www.php.net/manual/ja/language.oop5.late-static-bindings.php

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?