特殊方法的应用

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()方法
"; if(isset($this->$property_name)) { return($this->$property_name); } else { return(NULL); } } //__set()方法用来设置私有属性 private function __set($property_name, $value) { echo "在直接设置私有属性值的时候,自动调用了这个__set()方法为私有 属性赋值
"; $this->$property_name = $value; } } $p1=new Person(); //直接为私有属性赋值的操作, 会 `自动调用` __set()方法进行赋值 $p1->name="张三"; $p1->sex="男"; $p1->age=20; //直接获取私有属性的值, 会 `自动调用` __get()方法,返回成员属性的值 echo "姓名:".$p1->name."
"; echo "性别:".$p1->sex."
"; echo "年龄:".$p1->age."
";

以上代码如果不加上__get()和__set()方法,程序就会出错,因为不能在类的外部操作私有成员,而上面的代码是通过 自动调用 __get()和__set()方法来帮助我们直接存取封装的私有成员的。

__isset()方法

  • 如果在一个对象外面使用“isset()”这个函数去测定对象里面的成员是否被设定分两种情况:
  • 如果对象里面成员是公有的,我们就可以使用这个函数来测定成员属性。
  • 如果是私有的成员属性,这个函数就不起作用了,原因就是因为私有的被封装了,在外部不可见。
  • 在类里面加上一个 __isset() 方法就可以了,当在类外部使用 isset()函数来测定对象里面的私有成员是否被设定时, 就会 自动 调用类里的“__isset()”方法了帮我们完成这样的操作。
class Person
{
    private $name;
    private function __isset($nm)
    {
        echo "当在类外部使用isset()函数测定私有成员$nm时,自动调用
"; return isset($this->$nm); } } $p1 = new Person(); //在使用isset()函数测定私有成员时,`自动调用` __isset()方法帮我们完成,返回结果为true echo var_dump(isset($p1->name))."
";

__unset()方法

道理和__isset()方法一样,只不过是在对象的外部删除内部的私有成员时 自动调用 的。

class Person
{
    private $name;
    private function __unset($nm)
    {
        echo "当在类外部使用unset()函数来删除私有成员时自动调用的
"; 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."
"; } 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 ")不存在!
\n"; } } //产生一个Test类的对象 $test=new Test(); //调用对象里不存在的方法 $test->demo("one", "two", "three"); //程序不会退出可以执行到这里 echo "this is a test
";

以上程序执行结果:

你所调用的函数: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."
"; //串行化的字符串我们通常不去解析 $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."
"; } //指定串行化时把返回的数组中$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."
"; //串行化的字符串我们通常不去解析 $p2=unserialize($p1_string); //反串行化形成对象$p2重新赋值$age为40 $p2->say();

以上代码输出结果:

O:6:"Person":2:{s:4:"name";s:6:"张三";s:3:"age";i:20;}
我的名字叫:张三 性别: 我的年龄是:40

你可能感兴趣的:(特殊方法的应用)