[PHP] オーバーロード /   call()   callStatic()   set()   get()   isset()   unset()

オーバーロードは、メンバを動的に作成する方法で、マジックメソッド で処理される。アクセス不能メンバを操作しようとしたときに自動的に動作する。 ※PHP5におけるオーバーロード機能は、他の多くのオブジェクト指向言語とは意味が違う。

アクセス不能メンバ

アクセス不能メンバとは…

  • 未定義のメンバ
  • 可視性によりアクセス不可能なメンバ

メソッドのオーバーロード

メソッドのオーバーロードのための特殊メソッドには __call() と __callStatic() の2つがある。 __call() は アクセス不能メソッドをオブジェクトのコンテキストで実行したときに自動的に呼び出される。 __callStatic() はPHP5.3~。

mixed __call(string $method_name, array $method_arguments)

これらの関数はアクセス不能メソッドにアクセスしたとき、呼び出そうとしたアクセス不能メソッド名を第一引数に、そのアクセス不能メソッドに渡そうとした引数を第二引数(配列)に受け取って処理を行う。また、考えれば分かるけど__callStatic() は public static で宣言しないとダメ。

また、マジックメソッドなので引数や返り値は必ず上記の形式でなければならない。

<?php
class OverloadMethod
{
  public function __call($method, $argument)
  {
    echo "__call() is called.\n";
    return "METHOD | {$method} / ARGUMENT | " . serialize($argument) . "\n";
  }
  public static function __callStatic($method, $argument)
  {
    echo "__callStatic() is called.\n";
    return "METHOD | {$method} / ARGUMENT | " . serialize($argument) . "\n";
  }
  private $var = " method is called.\n";
  public function public_n(){
    echo "public", $this->var;
  }
  protected function protected_n(){
    echo "protected", $this->var;
  }
  public static function public_s(){
    echo "public static method is called.\n";
  }
  protected static function protected_s(){}
}
$static = "OverloadMethod";
$obj = new OverloadMethod;

$obj->public_n();
$obj->protected_n();
echo $obj->dummy("引数");
$static::public_s();
$static::protedted_s();
$static::dummy();
echo $static::protedted_n("arg1","arg2");
$static::public_n();
?>

結果

public method is called.
__call() is called.
__call() is called.
METHOD | dummy / ARGUMENT | a:1:{i:0;s:6:"引数";}
public static method is called.
__callStatic() is called.
__callStatic() is called.
__callStatic() is called.
METHOD | protedted_n / ARGUMENT | a:2:{i:0;s:4:"arg1";i:1;s:4:"arg2";}
Fatal error: Using $this when not in object context in *** on line 17

プロパティのオーバーロード

void __set( string $name, mixed $value )

アクセス不能プロパティに値をセットしようとすると起動する。 戻り値はなし。第一引数 : 値をセットしようとしたプロパティ名、第二引数 : セットしようとした値

mixed __get( mixed $name )

アクセス不能プロパティにアクセスしようとすると起動する。 返り値は mixed。 第一引数 : アクセスしようとしたプロパティ名

bool __isset( string $name )

isset() と empty() の引数にアクセス不能プロパティを入れると起動する。 返り値は boolean。 第一引数は isset/empty に入れたアクセス不能プロパティ名。

void __unset( string $name )

unset() をアクセス不能プロパティ 返り値はなし。 第一引数は unset しようとしたプロパティ名

__set()

<?php
class MagicMethod__set
{
  public function __set($name, $value){
    $this->inaccessible[$name] = $value ;
    return "無視されます";
  }
}
$class = "MagicMethod__set";
$obj = new $class;

$global_var = ($obj->dummy = "TEST");
echo '$global_var - ' . $global_var . ' / ';
echo '$obj->dummy - ';
echo isset($obj->dummy) ? $obj->dummy : 'NULL', "\n\n";
var_dump($obj);

$class::$dummy;
?>

結果

$global_var - TEST / $obj->dummy - NULL

object(MagicMethod__set)#1 (1) {
  ["inaccessible"]=>
  array(1) {
    ["dummy"]=>
    string(4) "TEST"
  }
}
Fatal error: Access to undeclared static property:
 MagicMethod__set::$dummy in *** on line 18

えーと、これは…勝手にプロパティを作成されたりするのを防いだりとかもできそうな感じかな。。

__get()

<?php
class MagicMethod__get
{
  public function __get($name)
  {
    echo __CLASS__ . "::\${$name} is undefined.\n";
    $this->{$name} = "お断りします";
    return "まあチクワでもたべなよ";
  }
}
$obj = new MagicMethod__get();
echo $obj->{"<`・ω・´>エスケープしろよ"};
var_dump($obj);
?>

結果

MagicMethod__get::$<`・ω・´>エスケープしろよ is undefined.
まあチクワでもたべなよ。
object(MagicMethod__get)#1 (1) {
  ["<`・ω・´>エスケープしろよ"]=>
  string(18) "お断りします"
}

__isset()

<?php
class MagicMethod__isset
{
  private $var;
  public function __construct()
  {
    empty($this->dummy) ? print("EMPTY.\n") : print "FALSE.\n";
    isset($this->dummy) ? print("ISSET.\n") : print "FALSE.\n";
    empty($this->dummy) ? print("EMPTY.\n") : print "FALSE.\n";
  }
  public function __isset($name)
  {
    echo "-----\n";
    $this->{$name} = "TEST";
    return TRUE;
  }
}
$o = new MagicMethod__isset();
isset($o->var) ? print "HOGE.\n" : exit ;
isset($o->var) ? print $o->var : exit ;
?>

結果

-----
EMPTY.
ISSET.
FALSE.
-----
HOGE.
Fatal error: Cannot access private property
 MagicMethod__isset::$var in *** on line 20

__unset()

<?php
class MagicMethod__unset
{
  private $pri_var = "private" ;
  public $pub_var = "public" ;
  public function __construct()
  {
    unset($this->pub_var);
  }
  public function __unset($name)
  {
    echo "now unset \${$name}.\n";
    unset($this->{$name});
    // return void
  }
  public function __get($name)
  {
    return "\${$name} is not defined.";
  }
  public function print_var($name)
  {
    echo "{$this->{$name}}\n";
  }
}
$obj = new MagicMethod__unset();
$obj->print_var('pub_var');

$obj->print_var('pri_var');
unset($obj->pri_var);
$obj->print_var('pri_var');
?>

結果

$pub_var is not defined.
private
now unset $pri_var.
$pri_var is not defined.
Share
関連記事