类中的魔术方法
PHP 魔术方法指的是在某些时刻会自动被调用的内置函数,它们以两个连续的下划线开头。
类中的魔术方法
__construct()
类的构造函数,用于初始化对象,在对象实例化时自动运行
__destruct()
析构函数,用于在 php 运行终止时,释放对象所占用的内存。析构函数是 php 的垃圾回收机制,使用栈结构,后进先出。
构造函数和析构函数的例子
123456789101112131415161718 | class computer{ private $brand ; function __construct( $brand ){ $this ->brand = $brand ; } function __destruct(){ echo "release " . $this ->brand. "<br>" ; } } $myComputer = new computer( "MAC" ); $yourComputer = new computer( "Asus" ); $hisComputer = new computer( "Dell" ); echo "end of php file<br>" ; |
输出结果如下所示
end of php filerelease Dellrelease Asusrelease MAC
可以发现析构函数在 php 文件执行结束之后才执行
__get($name)
类中用 protected 和 private 关键字定义的成员属性或方法是无法通过对象的实例访问的。__get() 方法会且仅会在对象的实例访问 proctected 和 private 成员属性 时自动执行 (访问成员方法时不会,因为没有意义)。
__get() 方法的意义在于将 proctected 和 private 成员属性进行处理后输出。
__get() 有且仅有一个输入参数
__get() 方法的一个例子
class computer{ private $brand ; protected $owner ; public $price ; function __construct( $brand , $owner , $price ){ $this ->brand = $brand ; $this ->owner = $owner ; $this ->price = $price ; } function __get( $name ){ echo "It's up to me to decide if let you konw the owner and the brand of this computer or not :)<br>" ; echo "I will tell you the name of woner: " . $this ->owner. "<br>" ; echo "I won't tell you that the brand is " .md5( $this ->brand). "<br>" ; echo "<br>" ; } function __destruct(){ echo "release " . $this ->brand. "<br>" ; } } $myComputer = new computer( "MAC" , "me" , "1000" ); $yourComputer = new computer( "Asus" , "you" , "500" ); $hisComputer = new computer( "Dell" , "his" , "700" ); echo $myComputer ->price; echo "<br><br>" ; echo $myComputer ->owner; echo $yourComputer ->brand; echo "end of php file<br>" ; |
输出如下
1000It's up to me to decide if let you konw the owner and the brand of this computer or not :)I will tell you the name of woner: meI won't tell you that the brand is 2e25c285356cbb0ed8785a1377027d79It's up to me to decide if let you konw the owner and the brand of this computer or not :)I will tell you the name of woner: youI won't tell you that the brand is cb6ab3315634a1e4d11b091ba48b60baend of php filerelease Dellrelease Asusrelease MAC
可以看到,当访问 public 成员属性 price 时,__get()方法并没有被调用。输出 brand 时,我们使用了 md5 对其进行了加密处理,这种对封装的成员属性进行处理后输出的用法就是 get 方法的意义所在。
__set($name, $value)
__set($name, $value) 与用于给当前类中封装的方法或属性进行重新赋值或定义。
与 get 类似但不同的时,__set($name, $value)会在成员属性被访问赋值时自动执行,其中 $name 是被访问的成员属性名,$value 为成员属性被赋予的值
__set() 的例子
class computer{ private $brand ; protected $owner ; function __construct( $brand , $owner , $price ){ $this ->brand = $brand ; $this ->owner = $owner ; $this ->price = $price ; } function __get( $name ){ echo "It's up to me to decide if let you konw the owner and the brand of this computer or not :)<br>" ; echo "I will tell you the name of woner: " . $this ->owner. "<br>" ; echo "I won't tell you that the brand is " .md5( $this ->brand). "<br>" ; echo "<br>" ; } function __set( $name , $value ){ $this ->owner = $value ; echo "set $name to $value" . "<br><br>" ; } function __destruct(){ echo "release " . $this ->brand. "<br>" ; } } $myComputer = new computer( "MAC" , "me" , "1000" ); echo $myComputer ->owner = "my friend" ; echo $myComputer ->owner; echo "end of php file<br>" ; |
输出结果
set owner to my friendmy friendIt's up to me to decide if let you konw the owner and the brand of this computer or not :)I will tell you the name of woner: my friendI won't tell you that the brand is 2e25c285356cbb0ed8785a1377027d79end of php filerelease MAC
我们看到在给 owner 赋值时调用了 set , 而访问属性时,调用了 get 。
__tostring()
用于直接打印对象句柄,也就是说当我们使用 echo 加对象名时,__torsring()将会被自动调用
__tosring() 例子
123456789 | class computer{ function __tostring(){ return "This is a computer class" ; } } $myComputer = new computer(); echo $myComputer ; |
如果没有 __totring() 方法,我们是无法使用 echo+对象名,会出现 fatal error
__call($method, $arguments)
当我们调用不存在的方法时,__call() 会自动执行,用于进行异常处理,并使程序继续正常运行。
__call() 例子
class computer{ function start(){ echo "starting computer<br>" ; } function __call( $m , $a ){ echo "erro function: " . $m ; echo "<br>" ; echo "error param: " ; print_r( $a ); echo "<br>" ; } } $myComputer = new computer(); $myComputer ->start(); $myComputer ->shutdown( '10 min' , '20 min' ); echo "here" ; |
输出结果为
starting computererro function: shutdownerror param: Array ( [0] => 10 min [1] => 20 min ) here
我们可以看到,$method 返回了错误的函数名,而 arguments 返回了参数,最后输出了 "here" 说明程序继续正常运行。
__clone() 方法 和 clone 关键字
clone 关键字用于复制对象,__clone() 方法实在克隆对象时自动调用的函数
clone 例子
class computer{ public $name ; function __clone(){ echo "A computer has been cloned<br>" ; } } $myComputer = new computer(); $youComputer = $myComputer ; $youComputer ->name = 'pc1' ; echo "My computer's name is " . $myComputer ->name. "<br>" ; echo "<br>" ; $hisComputer = clone $myComputer ; $hisComputer ->name = 'pc2' ; echo "My computer's name is " . $myComputer ->name. "<br>" ; echo "His computer's name is " . $hisComputer ->name. "<br>" ; |
输出结果
My computer's name is pc1A computer has been clonedMy computer's name is pc1His computer's name is pc2
我们看到用 = 号并不能复制对象,只是为对象添加了一个别名而已,这里 $myComputer 和 $youComputer 指向同一块内存,修改了 $youComputer 的值相当于修改了 $myComputer 的值。
__autolaod()
在实例化对象时,__autolaod() 会自动被调用,用于快速取得对应的类文件
__autoload() 例子
<?php function __autoload( $class_name ) { include $class_name . '.php' ; } $obj = new MyClass1(); $obj2 = new MyClass2(); ?> |
摘自PHP手册
带 try, catch 异常处理的例子
function __autoload( $class_name ){ echo "want to load " . $class_name . "<br>" ; if ( file_exists ( $class_name . ".class.php" )){ include ( $class_name . ".class.php" ); } else { throw new Exception( "Unable to laod " . $class_name . ".class.php" ); } } try { $obj = new myClass(); } catch (Exception $e ){ echo $e ->getMessage(). "<br>" ; } |
共同学习,写下你的评论
评论加载中...
作者其他优质文章