php中的魔术方法
2015-02-03 14:41
260 查看
PHP魔术方法:__construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone() 和 __debugInfo() 等方法在 PHP 中被称为"魔术方法"(Magic methods)。在命名自己的类方法时不能使用这些方法名,除非是想使用其魔术功能。
输出:在构造函数中在析构函数中__call()和__callStatic()在对象中调用一个不可访问方法时会调用这两个方法,后者为静态方法。
__construct(),类的构造函数 __destruct(),类的析构函数 __call(),在对象中调用一个不可访问方法(私有或者不存在)时调用 __callStatic(),用静态方式中调用一个不可访问方法时调用 __get(),获得一个类的成员变量时调用 __set(),设置一个类的成员变量时调用 __isset(),当对不可访问属性调用isset()或empty()时调用 __unset(),当对不可访问属性调用unset()时被调用。 __sleep(),执行serialize()时,先会调用这个函数 __wakeup(),执行unserialize()时,先会调用这个函数 __toString(),类被当成字符串时的回应方法 __invoke(),调用函数的方式调用一个对象时的回应方法 __set_state(),调用var_export()导出类时,此静态方法会被调用。 __clone(),当对象复制完成时调用__construct()和__destruct()构造函数__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'); ?>输出:array (size=2)0 => string 'in object context' (length=17)1 => string 'another arg' (length=11)object method runTest and in object context,another argstatic method runTest and in static context__get(),__set(),__isset()和__unset()当获取一个不可访问的类成员变量或设置一个不可访问的类成员变量时调用这两个函数。
<?php class 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); ?>输出:__setarray (size=1)'a' => string 'aaaa' (length=4)__getarray (size=1)'a' => string 'aaaa' (length=4)__issetnot set__unset__sleep()和__wakeup()当我们在执行serialize()和unserialize()时,会先调用这两个函数。例如我们在序列化一个对象时,这个对象有一个数据库链接,想要在反序列化中恢复链接状态,则可以通过重构这两个函数来实现链接的恢复。
<?php class 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) 0 => string '1' (length=1) 'id' => string '1' (length=1) 1 => string 'm0sh1' (length=5) 'username' => string 'm0sh1' (length=5) sleep wakeup object(Connection)[2] public 'link' => resource(6, mysql link) private 'server' => string 'localhost' (length=9) private 'username' => string 'moshi' (length=4) private 'password' => string 'moshi' (length=5) private 'db' => string 'test' (length=4) array (size=4) 0 => string '1' (length=1) 'id' => string '1' (length=1) 1 => string 'm0sh1' (length=5) 'username' => string 'm0sh1' (length=5)
__toString()对象当成字符串时的回应方法。例如使用echo $obj;
<?php输出:this is a object这个方法只能返回字符串,而且不可以在这个方法中抛出异常,否则会出现致命错误。__invoke()调用函数的方式调用一个对象时的回应方法。
class TestClass
{
public function __toString() {
return 'this is a object';
}
}$class = new TestClass();
echo $class;
?>
<?php输出:in invokeboolean trueboolean false__set_state()调用var_export()导出类时,此静态方法会被调用。
class 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));
<?php输出:object(A)[1]public 'var1' => int 5public 'var2' => string 'foo' (length=3)A::__set_state(array( 'var1' => 5, 'var2' => 'foo', ))object(A)[2]public 'var1' => string 'var11' (length=5)public 'var2' => string 'foo' (length=3)__clone()当对象复制完成时调用。
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);?>
<?php输出:equalClone is not allowed error: 256PHP 魔术常量:简介在这里
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;
?>
相关文章推荐
- 讲讲php的魔术方法
- php魔术方法
- PHP 5魔术方法应用浅析
- php 魔术方法使用说明详细
- php 魔术方法
- php的魔术方法
- PHP中的魔术方法总结 :__construct, __destruct , __call, __callStatic,__get, __set, __isset, __unset , __sleep, __wakeup, __toStr
- PHP下划线函数即魔术方法汇总
- PHP中的魔术方法总结 :__construct, __destruct , __call, __callStatic,__get, __set, __isset, __uns
- PHP中用魔术方法__autoload()实现类的自动加载
- 有了PHP 5.3的__callStatic魔术方法,就可以做按类名和方法名同时魔术了
- php魔术方法
- php魔术方法和魔术变量
- 腾讯php面试题总结(一) 15个魔术方法的总结
- PHP中的魔术方法总结
- php 魔术方法使用说明
- PHP中的魔术方法总结 :__construct,__destruct ,__call,__callStatic,__get,__set,__isset,__unset,__sleep,__wakeup, __toString.......
- PHP中的魔术方法总结[__construct/__destruct/__get/__set/__isset/__unset/__toString/__clone等]
- php魔术方法和魔术变量、内置方法和内置变量
- PHP魔术方法