定义:php 将所有以 (两个下划线)开头的类方法保留为魔术方法。所以在定义类方法时,除了上述魔术方法,建议不要以 为前缀。
作用:利用模式方法可以轻松实现php面向对象中重载(overloading即动态创建类属性和方法)
其实很多博客主已经写过这些方法了、、、但是我还是要说一遍。。谁让你来听了呢,码这么多字也不容易看完再走吧!
1.construct,destruct
constuct构建对象的时被调用;
destruct明确销毁对象或脚本结束时被调用;
class foo {
private $name;
private $link;
public function construct($name) {
$this->name = $name;
}
public function destruct() {
echo 'destroying: ', $this->name, php_eol;//php_eol代表php的换行符 }
}
打住,先安利一波重载的定义及使用方法:
定义:php所提供的"重载"(overloading)是指动态地"创建"类属性和方法。(我们是通过魔术方法(magic methods)来实现的)
作用:当调用当前环境下未定义或不可见的类属性或方法时,重载方法会被调用。后面将使用"不可访问属性(inaccessible properties)"和"不可访问方法(inaccessible methods)"来称呼这些未定义或不可见的类属性或方法。
注意:所有的重载方法都必须被声明为 public。
2.get、set、isset、unset、call、callstatic //为啥放一起呢?
set当给不可访问或不存在属性赋值时被调用
get读取不可访问或不存在属性时被调用
isset对不可访问或不存在的属性调用isset()或empty()时被调用
unset对不可访问或不存在的属性进行unset时被调用
call调用不可访问或不存在的方法时被调用
callstatic调用不可访问或不存在的静态方法时被调用
example #1 使用 get(),set(),isset() 和 unset() 进行属性重载
<?php
class propertytest {
/** 被重载的数据保存在此 */
private $data = array();
/** 重载不能被用在已经定义的属性 */
public $declared = 1;
/** 只有从类外部访问这个属性时,重载才会发生 */
private $hidden = 2;
public function set($name, $value)
{
echo "setting '$name' to '$value'\n";
$this->data[$name] = $value;
}
public function get($name)
{
echo "getting '$name'\n";
if (array_key_exists($name, $this->data)) {
return $this->data[$name];
}
$trace = debug_backtrace();
trigger_error(
'undefined property via get(): ' . $name .
' in ' . $trace[0]['file'] .
' on line ' . $trace[0]['line'],
e_user_notice);
return null;
}
/** php 5.1.0之后版本 */
public function isset($name)
{
echo "is '$name' set?\n";
return isset($this->data[$name]);
}
/** php 5.1.0之后版本 */
public function unset($name)
{
echo "unsetting '$name'\n";
unset($this->data[$name]);
}
/** 非魔术方法 */
public function gethidden()
{
return $this->hidden;
}
}
echo "<pre>\n";
$obj = new propertytest;
$obj->a = 1;
echo $obj->a . "\n\n";
var_dump(isset($obj->a));
unset($obj->a);
var_dump(isset($obj->a));
echo "\n";
echo $obj->declared . "\n\n";
echo "let's experiment with the private property named 'hidden':\n";
echo "privates are visible inside the class, so get() not used...\n";
echo $obj->gethidden() . "\n";
echo "privates not visible outside of class, so get() is used...\n";
echo $obj->hidden . "\n";
?>
看完了吗?好好看!
5.sleep,wakeup
sleep当使用serialize时被调用,当你不需要保存大对象的所有数据时很有用
wakeup当使用unserialize时被调用,可用于做些对象的初始化操作
<?php
class connection
{
protected $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()
{
return array('server', 'username', 'password', 'db');
}
public function wakeup()
{
$this->connect();
}
}
?>
6.clone
进行对象clone时被调用,用来调整对象的克隆行为
<?php
class subobject
{
static $instances = 0;
public $instance;
public function construct() {
$this->instance = ++self::$instances;
}
public function clone() {
$this->instance = ++self::$instances;
}
}
class mycloneable
{
public $object1;
public $object2;
function clone()
{
// 强制复制一份this->object, 否则仍然指向同一个对象
$this->object1 = clone $this->object1;
}
}
$obj = new mycloneable();
$obj->object1 = new subobject();
$obj->object2 = new subobject();
$obj2 = clone $obj;
print("original object:\n");
print_r($obj);
print("cloned object:\n");
print_r($obj2);
?>
7.tostring
当一个类被转换成字符串时被调用
<?php
class subobject
{
static $instances = 0;
public $instance;
public function construct() {
$this->instance = ++self::$instances;
}
public function clone() {
$this->instance = ++self::$instances;
}
}
class mycloneable
{
public $object1;
public $object2;
function clone()
{
// 强制复制一份this->object, 否则仍然指向同一个对象
$this->object1 = clone $this->object1;
}
}
$obj = new mycloneable();
$obj->object1 = new subobject();
$obj->object2 = new subobject();
$obj2 = clone $obj;
print("original object:\n");
print_r($obj);
print("cloned object:\n");
print_r($obj2);
?>
8.set_state
当调用var_export()导出类时,此静态方法被调用。用set_state的返回值做为var_export的返回值。
<?php
class a
{
public $var1;
public $var2;
public static function set_state($an_array) // as of php 5.1.0
{
$obj = new a;
$obj->var1 = $an_array['var1'];
$obj->var2 = $an_array['var2'];
return $obj;
}
}
$a = new a;
$a->var1 = 5;
$a->var2 = 'foo';
eval('$b = ' . var_export($a, true) . ';'); // $b = a::set_state(array(
// 'var1' => 5,
// 'var2' => 'foo',
// ));
var_dump($b);
?>
以上就是php中重载与魔术方法的示例详解的详细内容。