php基础巩固加强(八)

PHP重载

重载在面向对象里指的是根据方法的返回值或者参数类型以及数量具有多个同名方法,叫做方法的重载。PHP中不支持重载。

PHP重载: 当去访问一个不存在的或者权限不够的属性或者方法的时候,能够去触发一系列的魔术方法,这就是PHP的重载。

属性重载

访问不存在的或者权限不够的属性的时候,触发的魔术方法

__get(): 获取属性的时候会自动触发 

demo如下:

//PHP属性重载
class Person
{
    //属性
    public $name;
    protected $money;
    private $age;

    //构造方法
    public function __construct($name,$money,$age)
    {
        $this->name = $name;
        $this->age  = $age;
        $this->money  = $money;
    }

    //增加一个魔术方法__get
    //__get方法必须要一个参数,需要访问的属性的名字
    public function __get($name){
        //var_dump($name);
        $allow = array('money','age');

        //让用户访问
        //如果用户访问的是money和tail,那么就帮助用户去访问,如果是其他返回FALSE
        if(in_array($name,$allow))
        {
            return $this->$name;   //$name叫做可变变量,注意这里访问的是传进来的$name不是$this->name;
        }
        else
        {
            //不存在
            return false;
        }
    }
}

//实例化
$person = new Person('马浩洋',6000,28);

//访问个人信息
echo $person->name;          //可以,访问公有属性
//echo $person->age;     //不可以,age是私有属性,且Person类没有__get()方法的时候

//Person类增加__get()方法之后
echo $person->age;

//访问一个不存在的
var_dump($person->tail);

这样做的意义如下:

1. 增加代码的容错性(不会产生错误提示)

2. 能够控制用户的访问


__set(): 当用户在设置属性的时候会自动触发的方法

demo如下:

class Person
{
    //魔术方法__set()
    //必须需要两个参数:属性名,属性值
    public function __set($property,$value)
    {
        //增加属性
        //$this->$property = $value;

        //这里我们可以设置允许用户添加那些属性
        $allow = array('name','age','tail'); //允许用户添加 name,age,tail属性

        //如果当前用户要设置的属性在$allow中存在 那么就可以添加用户当前要设置的属性
        if(in_array($property,$allow))
        {
            $this->$property = $value;
        }

    }
}

//实例化Person类的对象
$person = new Person();

//给对象增加属性
//$person->test = 'hello world';   //用户设置属性的时候自动触发__set()魔术方法,这里的test属性就是对应__set()里的$property,而test对应的值hello world就是对应__set()里的$value

//echo $person->test;  //输出:hello world


//给对象增加一个不允许添加的属性
$person->drag = '拖拽';  //由于__set()魔术方法的控制 手动添加的drag属性不会被添加成功

var_dump($person); //$person对象没有drag属性

//给对象增加一个允许添加的属性
$person->name = '周鸿祎';  //__set()内部允许添加name属性  所以name属性添加成功
var_dump($person);        //$person对象有name属性

__isset(): 当用isset()和empty()判断对象不可见的属性时(protected/private/不存在的属性)会自动触发__isset()魔术方法来执行 

demo如下:

class Person
{
    public  $name;
    private $age;

    //构造方法
    public function __construct($name,$age)
    {
        $this->name = $name;
        $this->age  = $age;
    }


    //重点来了 看以下注释和代码

    //当用isset()和empty()判断对象不可见的属性时(protected/private/不存在的属性)会自动触发__isset()来执行
    //__isset()魔术方法 必须需要一个参数知道要判断的属性名字
    public function __isset($key)
    {
        //var_dump($key);   //这里的$key就是对应下面的age属性
        return isset($this->$key);
    }

}

//实例化对象
$wzyl = new Person('马云',60);

var_dump(isset($wzyl->name));  //输出:true
var_dump(isset($wzyl->age));  //输出:false(这个时候还有把__isset()魔术方法显示的写出来)  因为age是private(私有的)不能在外部访问 所以isset()检测不到age 所以是false


//由于isset无法在类的外部判断受保护(protected)的和私有(private)的属性是否存在,这个时候就会触发__isset()魔术方法
var_dump(isset($wzyl->age)); //输出:true

__unset(): 当用unset销毁对象的不可见属性时(protected/private),会自动触发__unset()魔术方法

demo如下:

class Person
{
    public  $name;
    private $age;

    //构造方法
    public function __construct($name,$age)
    {
        $this->name = $name;
        $this->age  = $age;
    }


    //增加__unset()方法 必须需要一个参数 表示要unset谁
   //当用unset销毁对象的不可见属性时(protected/private),会自动触发__unset()魔术方法
    public function __unset($property)
    {
        //var_dump($property);  这里的$property就是下面类的外部的age属性
        unset($this->$property);
    }

}

//实例化一个对象
$person = new Person('web',19);

echo "<pre>";

//var_dump($person); //$person有name属性和age属性

//删除属性
//unset($person->name);   //共有(public)属性可以被删除

//var_dump($person);   //由于刚刚unset了name属性 此时$person只剩下一个age属性了

//删除私有属性
//unset($person->age); //报错(此时还没有将__unset()魔术方法显示的写出来),因为受保护的和私有的属性不能在类的外部访问

/*************************************************************************/
//在类的内部增加了__unset()魔术方法之后 在来unset外部不能访问的属性age

var_dump($person); //此时$person对象有name和age属性
unset($person->age); //已经删除了私有的age属性

var_dump($person);  //此时$person对象只有name属性了

方法重载

当访问一个权限不够或者不存在的方法的时候,会自动触发的方法

__call(): 访问一个非静态方法

__callStatic(): 访问一个静态方法

demo如下:

//PHP方法重载

class Person
{
    //方法
    private function test()
    {
        echo __METHOD__;
    }

    protected static function test1()
    {
        echo __METHOD__;
    }

    //增加一个魔术方法__call()用来给类的外部对象访问权限不足的非静态方法,也就是说 当在类的外部访问使用protected/private修饰的静态方法的时候,会自动触发此魔术方法
    //必须有两个参数 第一个参数是方法名字,第二个是参数数组
    public function __call($name,$args)
    {
        //var_dump($name);  //方法名字
        //var_dump($args); //参数数组

        //定义一个允许访问的方法的数组
        $allow = array('test');

        if(in_array($name,$allow))
        {
            $this->$name();    //可变方法
        }
        else
        {
            return false;
        }

    }

    //增加一个魔术方法__callStatic()用来访问不能在类的外部访问的静态方法,也就是说 当在类的外部访问使用protected/private修饰的静态方法的时候,会自动触发此魔术方法
    //必须有两个参数 第一个参数是方法名字,第二个是参数数组
    public static function __callStatic($name,$args)
    {
        //var_dump($name);  //方法名字
        //var_dump($args); //参数数组

        //定义一个允许访问的方法的数组
        $allow = array('test1');

        if(in_array($name,$allow))
        {
            self::$name();  //可变方法
        }
        else
        {
            return false;
        }

    }

}

//实例化一个对象
$person = new Person();

//访问私有方法,此时还没有魔术方法
//$person->test();  //报错
//Person::test1();  //同样报错


/***********************************/
//增加__call()魔术方法之后
//$person->test();  //输出:Person::test 说明已经访问到了
//var_dump($person->test1());  //输出false  因为Person类的内部已经使用__call()魔术方法限制了只能允许方法test方法


//增加__callStatic()魔术方法之后
Person::test1();  //输出:Person::test1  说明我们在增加了__callStatic()魔术方法之后 我们确实在类的外部访问到了使用protected修饰的静态方法

php重载的意义:

1. 控制对象或者类的允许操作的范围

2. 容错处理


声明:禁止任何非法用途使用,凡因违规使用而引起的任何法律纠纷,本站概不负责。

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

精彩评论

全部回复12人评论7,777人参与