4 魔术方法

1       魔术方法

1.1    __set方法

_set() 方法用于设置私有属性值;在类里面使用了 __set() 方法后,当使用 $Person->name = "小红"; 这样的方式去设置对象私有属性的值时,就会自动调用 __set() 方法来设置私有属性的值。

复制代码
class Person{
       private $name;private $age;
       public function __construct($name="",  $age=25){
           $this->name = $name;
           $this->age  = $age;
       }
       /**
        * 声明魔术方法需要两个参数,真接为私有属性赋值时自动调用,并可以屏蔽一些非法赋值
        * @param $property
        * @param $value
        */
       public function __set($property, $value) {
           if ($property=="age"){
               if ($value > 150 || $value < 0) {
                   return;
               }
           }
           $this->$property = $value;
       }
       /**
        * 在类中声明说话的方法,将所有的私有属性说出
        */
       public function say(){
           echo "我叫".$this->name.",今年".$this->age."岁了";
       }
   }
   $Person=new Person("小明", 25); //注意,初始值将被下面所改变
   //自动调用了__set()函数,将属性名name传给第一个参数,将属性值”李四”传给第二个参数
   $Person->name = "小红";     //赋值成功。如果没有__set(),则出错。
   //自动调用了__set()函数,将属性名age传给第一个参数,将属性值26传给第二个参数
   $Person->age = 16; //赋值成功
   $Person->age = 160; //160是一个非法值,赋值失效
   $Person->say();  //输出:我叫小红,今年16岁了
复制代码

1.2    __get方法

在 php 面向对象编程中,类的成员属性被设定为 private 后,如果我们试图在外面调用它则会出现“不能访问某个私有属性”的错误。那么为了解决这个问题,我们可以使用魔术方法 __get()。

在程序运行过程中,通过它可以在对象的外部获取私有成员属性的值。

复制代码
class Person {

       private $name;

       private $age;

       function __construct($name="", $age=1){
           $this->name = $name;
           $this->age = $age;
       }
       /**
        * 在类中添加__get()方法,在直接获取属性值时自动调用一次,以属性名作为参数传入并处理
        * @param $propertyName
        *
        * @return int
        */
       public function __get($propertyName) {  
           if ($propertyName == "age") {
               if ($this->age > 30) {
                   return $this->age - 10;
               } else {
                   return $this->$propertyName;
               }

           } else {
               return $this->$propertyName;
           }
       }
   }
   $Person = new Person("小明", 60);   // 通过Person类实例化的对象,并通过构造方法为属性赋初值

   echo "姓名:" . $Person->name . "

   ";   // 直接访问私有属性name,自动调用了__get()方法可以间接获取

   echo "年龄:" . $Person->age . "

   ";    // 自动调用了__get()方法,根据对象本身的情况会返回不同的值
复制代码

 

1.3    __clone方法

__clone方法可以将某个对象直接复制一份

复制代码
class Sheep{

    public $name;

    protected $food;

    public function __construct($name,$food){

        $this->name = $name;

        $this->food = $food;

    } 

}

$sheep1 = new Sheep("dorly","grass");

$sheep2 = clone $sheep1;

if($sheep1 == $sheep2){//这里输出的是相等

    echo "相等";

}else{

    echo "不相等";

}

if($sheep1 === $sheep2){//这里是不相等

    echo "相等";

}else{

    echo "不相等";

}
复制代码
复制代码
class Sheep{

    public $name;

    protected $food;

    public function __construct($name,$food){

        $this->name = $name;

        $this->food = $food;

    } 

    public function __clone(){

        $this->food = 'meat';

    }

}

$sheep1 = new Sheep("dorly","grass");

$sheep2 = clone $sheep1;

if($sheep1 == $sheep2){//这里输出的是不相等

    echo "相等";

}else{

    echo "不相等";

}
复制代码

说明:

(1)           当$对象1 = clone $对象2,会触发__clone方法

(2)           如果我们希望在克隆是,修改某个属性,则在__clone方法种修改即可

(3)           如果我们希望阻止克隆,只需要将__clone魔术方法申明为private即可

1.4    __call方法

l  基本介绍

(1)           当调用不可访问的成员方法时就会调用__call魔术方法

(2)           不可访问的成员方法指的是(1.方法不存在2.成员方法时protected或者private)

l  代码案例

复制代码
class Monk{

    public $name;

    protected $hobby;

    public function __construct($name,$hobby){

        $this->name = $name;

        $this->food = $hobby;

    }

    //该方法有两个参数,第一个参数会自动接收不存在的方法名,

    //第二个参数则以数组的方式接收不存在方法的多个参数。 

    public function __call($function_name,$parameters){

        if(method_exists($this,$function_name)){

            return $this->$function_name($parameters[0],$parameters[1]);

        }else{

            echo "此函数不存在";

        }

    }

    protected function getSum($num1,$num2){

        return $num1+$num2;

    }

}

$monk = new Monk("济公","喝酒");

echo "计算结果:".$monk->getSum(100,200);

 
复制代码

 

本文作者:xiaoovo

本文链接:https://www.cnblogs.com/xiaoovo/p/15968127.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   xiaoovo  阅读(67)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
🔑