特殊方法的应用

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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,179评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,229评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,032评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,533评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,531评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,539评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,916评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,813评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,568评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,654评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,354评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,918评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,152评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,852评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,378评论 2 342

推荐阅读更多精彩内容

  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,849评论 6 13
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,580评论 18 139
  • 一.自我介绍 一个人的自我介绍是给别人除视觉以外的另一个刺激。那怎么算是抓住别人眼球的自我介绍呢?我从今天64位伙...
    6玲子6阅读 300评论 2 3
  • 成份详解: 海藻胶: 选取生长于海底3~6米处的海藻,经自然提取所得的海藻粉,制作成冻,爽滑适口,具有保湿,去皱...
    FAB洋洋阅读 613评论 0 0