title: 特殊方法的应用
date: 2015-01-17 17:41:56
categories: 面向对象
tags:
__get($propertyName)方法
- 获取私有成员属性值
- 有一个参数,$propertyName 是获取成员属性的名称
- 返回值:获取属性的值
- 当我们在对象的外部调用私有属性的时候
自动
调用的。 - 如果成员属性不封装成私有的,对象本身就不会去自动调用这个方法。
- 如果没有设置__get(),在对象的外部是不允许调用内部私有属性的。
__set($property_name, $value)方法
- 用来为私有成员属性设置值的。
- 第一个参数为你要为设置值的属性名,第二个参数是要给属性设置的值。
- 返回值:无。
- 在对象外部直接设置私有属性值的时候
自动
调用的,同样属性私有的已经被封装上了。 - 如果成员属性不封装成私有的,对象本身就不会去自动调用这个方法。
- 如果没有设置__set(),在对象的外部是不允许设置私有属性的。
class Person
{
//下面是人的成员属性, 都是封装的私有成员
private $name; //人的名字
private $sex; //人的性别
private $age; //人的年龄
//__get()方法用来获取私有属性
private function __get($property_name)
{
echo "在直接获取私有属性值的时候,自动调用了这个__get()方法<br>";
if(isset($this->$property_name))
{
return($this->$property_name);
}
else
{
return(NULL);
}
}
//__set()方法用来设置私有属性
private function __set($property_name, $value)
{
echo "在直接设置私有属性值的时候,自动调用了这个__set()方法为私有 属性赋值<br>";
$this->$property_name = $value;
}
}
$p1=new Person();
//直接为私有属性赋值的操作, 会 `自动调用` __set()方法进行赋值
$p1->name="张三";
$p1->sex="男";
$p1->age=20;
//直接获取私有属性的值, 会 `自动调用` __get()方法,返回成员属性的值
echo "姓名:".$p1->name."<br>";
echo "性别:".$p1->sex."<br>";
echo "年龄:".$p1->age."<br>";
以上代码如果不加上__get()和__set()方法,程序就会出错,因为不能在类的外部操作私有成员,而上面的代码是通过 自动调用
__get()和__set()方法来帮助我们直接存取封装的私有成员的。
__isset()方法
- 如果在一个对象外面使用“isset()”这个函数去测定对象里面的成员是否被设定分两种情况:
- 如果对象里面成员是公有的,我们就可以使用这个函数来测定成员属性。
- 如果是私有的成员属性,这个函数就不起作用了,原因就是因为私有的被封装了,在外部不可见。
- 在类里面加上一个
__isset()
方法就可以了,当在类外部使用isset()
函数来测定对象里面的私有成员是否被设定时, 就会自动
调用类里的“__isset()”方法了帮我们完成这样的操作。
class Person
{
private $name;
private function __isset($nm)
{
echo "当在类外部使用isset()函数测定私有成员$nm时,自动调用<br>";
return isset($this->$nm);
}
}
$p1 = new Person();
//在使用isset()函数测定私有成员时,`自动调用` __isset()方法帮我们完成,返回结果为true
echo var_dump(isset($p1->name))."<br>";
__unset()方法
道理和__isset()方法一样,只不过是在对象的外部删除内部的私有成员时 自动调用
的。
class Person
{
private $name;
private function __unset($nm)
{
echo "当在类外部使用unset()函数来删除私有成员时自动调用的<br>";
unset($this->$nm);
}
}
$p1 = new Person();
//在使用unset()函数删除私有成员时,`自动调用` __unset()方法帮我们完成,删除name私有属性
unset($p1->name);
__set()
、__get()
、__isset()
、__unset()
这四个方法都是我们添加到对象里面的,在需要时 自动调用
的,来完成在对象外部对对象内部私有属性的操作。
__toString()方法
- 在直接输出对象引用时
自动调用
的,比如
class TestClass
{
public $foo;
public function __construct($foo)
{
$this->foo = $foo;
}
//定义一个__toString方法,返加一个成员属性$foo
public function __toString()
{
return $this->foo;
}
}
$class = new TestClass('Hello');
//直接输出对象
echo $class; //这个时候会 `自动调用` TestClass类里面的 __toString()方法,如果不定义__toString()方法,程序会报错
clone 克隆对象
$p1=new Person("张三", "男", 20);
//使用“clone”克隆新对象 p2,和 p1 对象具有相同的属性和方法。
$p2=clone $p1;
$p2->say();
__clone() 方法
- 对象克隆时
自动调用
的方法。 - 自动包含
$this
和$that
两个指针,$this
指向复本,而$that
指向原本。
class Person
{
//下面是人的成员属性
var $name; //人的名字
var $sex; //人的性别
var $age; //人的年龄
//定义一个构造方法参数为属性姓名$name、性别$sex 和年龄$age 进行赋值
function __construct($name="", $sex="", $age="")
{
$this->name=$name;
$this->sex=$sex;
$this->age=$age;
}
//这个人可以说话的方法, 说出自己的属性
function say()
{
echo "我的名字叫:".$this->name." 性别:".$this->sex." 我的年龄是:".$this->age."<br>";
}
function __clone()
{
//$this 指的复本 p2, 而$that 是指向原本 p1,这样就在本方法里,改变了复本的属性。
$this->name="我是假的$that->name";
$this->age=30;
}
}
$p1=new Person("张三", "男", 20);
$p2=clone $p1;
$p1->say();
$p2->say();
执行结果是:
我的名字叫:张三 性别:男 我的年龄是:20
我的名字叫:我是假的张三 性别:男 我的年龄是:30
__call() 方法
- 使用对象调用内部方法时候,不存在该方法,那么程序就会出错,然后程序退出不能继续执行。
- __call() 就是调用不存在方法的时候
自动调用
的
class Test
{
//调用不存的方法时自动调用的方法,第一个参数为方法名,第二个参数是数组参数
function __call($function_name,$args)
{
print "你所调用的函数:$function_name(参数:";
print_r($args);
print ")不存在!<br>\n";
}
}
//产生一个Test类的对象
$test=new Test();
//调用对象里不存在的方法
$test->demo("one", "two", "three");
//程序不会退出可以执行到这里
echo "this is a test<br>";
以上程序执行结果:
你所调用的函数:demo(参数:Array ( [0] => one [1] => two [2] => three ) )不存在!
this is a test.
unserialize()
- 为了方便把一个对象在网络上传输,可以把整个对象转换为二进制串,传输到目的地时,再还原为原来的对象,这个过程称之为串行化。
-
serialize()
串行化一个对象; -
unserialize()
反串行化对象;
$p1=new Person("张三", "男", 20);
$p1_string=serialize($p1); //把一个对象串行化,返一个字符串
echo $p1_string."<br>"; //串行化的字符串我们通常不去解析
$p2=unserialize($p1_string); //把一个串行化的字符串反串行化形成对象$p2
__sleep()
- 对象串行化的时候会调用该方法。
- 函数不接受任何参数, 但返回一个数组,其中包含需要串行化的属性。
- 末被包含的属性将在串行化时被忽略。
- 如果没有__sleep()方法,PHP 将保存所有属性。
- 在对象使用serialize()序列化的时候
自动调用
的。
__wakeup()
- 由二进制串重新组成一个对象的时候,则会
自动调用
__wakeup(),做一些对象醒来就要做的动作。
class Person
{
public $name;
public $sex;
public $age;
//定义一个构造方法参数为属性姓名$name、性别$sex 和年龄$age 进行赋值
function __construct($name="",$sex="",$age="")
{
$this->name = $name;
$this->sex = $sex;
$this->age = $age;
}
//这个人可以说话的方法, 说出自己的属性
function say()
{
echo "我的名字叫:".$this->name." 性别:".$this->sex." 我的年龄是:".$this->age."<br>";
}
//指定串行化时把返回的数组中$name 和$age 值串行化,忽略没在数组中的属性$sex
function __sleep()
{
$arr = array("name","age");
return $arr;
}
//重新生成对象时,并重新赋值$age为40
function __wakeup()
{
$this->age = 40;
}
}
$p1=new Person("张三", "男", 20);
//把一个对象串行化,返一个字符串,调用了__sleep()方法,忽略没在数组中的属性$sex
$p1_string=serialize($p1);
echo $p1_string."<br>"; //串行化的字符串我们通常不去解析
$p2=unserialize($p1_string); //反串行化形成对象$p2重新赋值$age为40
$p2->say();
以上代码输出结果:
O:6:"Person":2:{s:4:"name";s:6:"张三";s:3:"age";i:20;}
我的名字叫:张三 性别: 我的年龄是:40