ホームページ >バックエンド開発 >PHPチュートリアル >PHPのイリュージョンメソッド
PHP のマジック メソッド <br>
PHP マジック メソッド: <br>
__construct()、__destruct()、__call()、__callStatic( ) 、__get()、__set()、__isset()、__unset()、__sleep()、__wakeup()、__toString()、__invoke()、__set_state()、__clone()、__debugInfo()、および PHP のその他のメソッドは次のとおりです。いわゆる「マジックメソッド」。マジック機能を使用しない限り、独自のクラス メソッドに名前を付けるときにこれらのメソッド名を使用することはできません。 <br>
<br>
__construct(),类的构造函数__destruct(),类的析构函数__call(),在对象中调用一个不可访问方法(私有或者不存在)时调用__callStatic(),用静态方式中调用一个不可访问方法时调用__get(),获得一个类的成员变量时调用__set(),设置一个类的成员变量时调用__isset(),当对不可访问属性调用isset()或empty()时调用__unset(),当对不可访问属性调用unset()时被调用。__sleep(),执行serialize()时,先会调用这个函数__wakeup(),执行unserialize()时,先会调用这个函数__toString(),类被当成字符串时的回应方法__invoke(),调用函数的方式调用一个对象时的回应方法__set_state(),调用var_export()导出类时,此静态方法会被调用。__clone(),当对象复制完成时调用
__construct() および __destruct()<br>オブジェクトの作成時にコンストラクター __construct() が使用されます。 、オブジェクトが消滅するとデストラクター __destruct() が呼び出されます
<?php  class ConDes{    protected $a = '';    function __construct(){        echo '在构造函数中<br>'; } function __destruct(){ echo '在析构函数中<br>'; }}$val = new ConDes();unset($val);?><pre name="code" class="php">出力:
構築中 関数内では、デストラクターでは、アクセスできないメソッドがオブジェクト内で呼び出されたときに、
__call() と __callStatic() が呼び出されます。後者は静的メソッドです。
<?php class MethodTest { public function __call ($name, $arguments) { var_dump($arguments); echo "object method $name and ".implode(',',$arguments)."<br>"; } public static function __callStatic ($name, $arguments) { echo "static method $name and ".implode(',',$arguments)."<br>"; }}$obj = new MethodTest;$obj->runTest('in object context','another arg');MethodTest::runTest('in static context'); ?>出力:
配列 (サイズ = 2)<br> 0 => 文字列 'オブジェクト コンテキスト内' (長さ = 17)<br> 1 => 文字列 '別の引数' (長さ=11)<br><br>オブジェクト メソッド runTest およびオブジェクト コンテキスト内、別の引数<br>静的メソッド runTest および静的コンテキスト内
<br>
__get()、__set()、__isset()、__unset()<br><br> これら 2 つは、アクセスできないクラス メンバー変数を取得するとき、またはアクセスできないクラス メンバー変数関数を設定するときに呼び出されます。 <br>
<?phpclass MethodTest { private $data = array(); private $a = ''; public $bbb = ''; public function __set($name, $value){ $this->data[$name] = $value; echo '__set'; var_dump($this->data); } public function __get($name){ echo '__get'; var_dump($this->data); if(array_key_exists($name, $this->data)) return $this->data[$name]; return NULL; } public function __isset($name){ echo '__isset'; return isset($this->data[$name]); } public function __unset($name){ echo '__unset'; unset($this->data[$name]); }}$in = new MethodTest();$in->a = 'aaaa';$aaa = $in->a;$res = isset($in->c)? 'set':'not set';echo '<br>'.$res.'<br>';unset($in->a);?>出力:
__set<br>array (size=1)<br> 'a' => length=4)<br>__get<br>array (size=1)<br> 'a' => string 'aaaa' (length=4)<br>__isset<br>設定されていません<br>__unset
<br>
__sleep() と __wakeup()<br><br>serialize() と unserialize() を実行すると、これら 2 つの関数が最初に呼び出されます。たとえば、オブジェクトをシリアル化する場合、そのオブジェクトにはデータベース リンクが含まれており、逆シリアル化中にリンク状態を復元したい場合は、これら 2 つの関数を再構築することでリンクを復元できます。
<span class="hljs-preprocessor"><code class="php hljs "><span class="hljs-preprocessor"></span>
<?phpclass Connection {    public $link;    private $server, $username, $password, $db;        public function __construct($server, $username, $password, $db)    {        $this->server = $server; $this->username = $username; $this->password = $password; $this->db = $db; $this->connect(); } private function connect() { $this->link = mysql_connect($this->server, $this->username, $this->password); mysql_select_db($this->db, $this->link); } public function __sleep() { echo 'sleep<br>'; return array('server', 'username', 'password', 'db'); } public function __wakeup() { echo 'wakeup<br>'; $this->connect(); }}$a = new Connection('localhost','mosi','moshi','test');$sql = 'select id,username from user limit 1';$res = mysql_query($sql,$a->link);$res = mysql_fetch_array($res);var_dump($res);$sres = serialize($a);mysql_close($a->link);//unset($a);$unsres = unserialize($sres);var_dump($unsres);$sql = 'select id,username from user limit 1';$ress = mysql_query($sql,$unsres->link);$ress = mysql_fetch_array($ress);var_dump($ress);?>出力:
array (size=4)<span class="hljs-preprocessor">array (size=4)<br> 0 => string '1' (length=1)<br> 'id' => string '1' (length=1)<br> 1 => string 'm0sh1' (length=5)<br> 'username' => string 'm0sh1' (length=5)<br>sleep<br>wakeup<br>object(Connection)[2]<br> public 'link' => resource(6, mysql link)<br> private 'server' => string 'localhost' (length=9)<br> private 'username' => string 'moshi' (length=4)<br> private 'password' => string 'moshi' (length=5)<br> private 'db' => string 'test' (length=4)<br>array (size=4)<br> 0 => string '1' (length=1)<br> 'id' => string '1' (length=1)<br> 1 => string 'm0sh1' (length=5)<br> 'username' => string 'm0sh1' (length=5)</span>
0 => 文字列 '1' (length=1)
1 => 文字列 'm0sh1' (長さ=5)<span class="hljs-preprocessor"><br></span>
'ユーザー名' => 文字列 'm0sh1' (長さ=5)
ウェイクアップ <span class="hljs-preprocessor">__toString()<br><br>对象当成字符串时的回应方法。例如使用echo $obj;</span>
object(Connection)[2]
private 'server' => string 'localhost' (length=9)<span class="hljs-preprocessor"></span>
private 'username' = > 文字列 'moshi' (長さ = 4)
<?php class TestClass { public function __toString() { return 'this is a object'; }}$class = new TestClass();echo $class; ?>プライベート 'db' => 🎜>配列 (サイズ = 4)
0 => 文字列 '1' (長さ = 1)
'id' => 文字列 '1' (長さ = 1) 1 => 文字列'm0sh1' (length=5)<span class="hljs-preprocessor"></span>
'username' => 文字列 'm0sh1' (length=5)<span class="hljs-preprocessor"></span>
<span class="hljs-preprocessor"><br></span>
<br><span class="hljs-preprocessor">__toString() </span>
オブジェクトが文字列として扱われる場合の応答メソッド。たとえば、 echo $obj;<br><br>
<span class="hljs-preprocessor"><p></p></span>
を使用します。 <?phpclass Invoke{ public function __invoke(){ echo 'in invoke<br>'; }}class noInvoke{}$obj = new Invoke();$obj();var_dump(is_callable($obj));$obj2 = new noInvoke();//$obj2();var_dump(is_callable($obj2));出力: <br>
<span class="hljs-preprocessor"><p></p></span>
<br>
これはオブジェクトです<br>このメソッドは文字列のみを返すことができ、このメソッドで例外をスローすることはできません。そうでない場合は、致命的なエラーが発生します。 <br>
<br><br>__invoke()<br>
関数呼び出しでオブジェクトを呼び出す際の応答メソッド。<?php class A { public $var1; public $var2; public static function __set_state ($arr) { $obj = new A; $obj->var1 = 'var11'; $obj->var2 = $arr['var2']; return $obj; }}$a = new A;$a->var1 = 5;$a->var2 = 'foo';var_dump($a); var_export($a); eval('$ress = '.var_export($a,true).';');var_dump($ress);?>出力:
in invoke<br>boolean true<br>boolean false<br><br><br><br>
__set_state()<br>この静的メソッドは、クラスをエクスポートするために var_export() を呼び出すときに呼び出されます。
<br><br>
<?php class Singleton { private static $_instance = NULL; // 私有构造方法 private function __construct() {} public static function getInstance() { if (is_null(self::$_instance)) { self::$_instance = new Singleton(); } return self::$_instance; } // 防止克隆实例 public function __clone(){ die('Clone is not allowed error: ' . E_USER_ERROR); }}$a = Singleton::getInstance();$b = Singleton::getInstance();if( $a === $b ){ echo 'equal<br>';}$c = clone $b;?>出力: <br>
object(A)[1]
public 'var1' => int; 5public 'var2' => string 'foo' (length=3)<br>A::__set_state(array( 'var1' => 5, 'var2' => 'foo', ))
object(A)[2]public 'var1' => string 'var11' (length=5)<br> public 'var2' => string 'foo' (length=3)<br>