封装性是对面对象的三大特性之一,封装就是把对象中的成员属性和成员方法加上访问修饰符,使其隐藏对象内部的细节,达到对成员访问的控制(并非拒绝访问)。
3种修饰符
- public (公有的 默认)
- private (私有的)
- protect (受保护的)
4种魔术方法
<?phpclass Person{public $name = "zhijia"; // 公有的private $age = 27; // 私有的protected $money = 10; // 受保护的private function getAge(){// 私有的成员方法 不能在类的外部访问return $this->age;}protected function getMoney(){// 被保护的成员方法 不能在类的外部访问return $this->money;}public function card(){echo $this->getName().$this->getMoney();}}$xw = new Person();echo $xw->age;echo $xw->money;echo $xw->getAge();echo $xw->getMoney();
上面代码会输出 没有权限访问 age、money、getAge()、getMoney();这里如果访问card() 那么就会正常输出moeny、age的值。
__set()
<?phpclass Person{private $name = "zhijia"; // 私有的private $age = 27; // 私有的protected $money = 10; // 受保护的private function getAge(){// 私有的成员方法 不能在类的外部访问return $this->age;}protected function getMoney(){// 被保护的成员方法 不能在类的外部访问return $this->money;}public function card(){echo $this->name.$this->getAge().$this->getMoney();}public function __set($key, $value){// 数据劫持 两个参数 一个是属性名 一个是对应的值// 并且该方法只针对 private 私有的属性 和 protected 受保护的属性有效if($key == "name" && $value == "laowang"){$this->name = "xiaowang";}}}$xw = new Person();$xw->name = "laowang";$xw->card();
这样name就变成了”xiaowang”,通过修改私有属性,可以触发 __set 方法。这样我们就可以做到数据的劫持。
__get()
<?phpclass Person{private $name = "zhijia"; // 私有的private $age = 27; // 私有的protected $money = 10; // 受保护的public function __get($key){// 数据劫持 参数是属性名// 并且该方法只针对 private 私有的属性 和 protected 受保护的属性有效if ($key == "age") {return "girl not tell you";}}}$xw = new Person();echo $xw->age;
这里我们就可以看到输出了 “gril not tell you”,因为访问私有属性的时候被数据被劫持了。并给我们返回了一句话。
__isset()
<?phpclass Person{private $x = 123;public function __isset($key){if($key == "x"){return true;}}}$xw = new Person();var_dump(isset($xw->x));
页面输出boole(true)。iseet方法会检查类里面有没有这个私有属性,如果不通过数据劫持,那么因为是私有属性会永远输出false。毕竟私有属性是不允许在类外部访问的。
__unset()
<?phpclass Person{private $x = 123;public function __unset($key){if($key == "x"){unset($this->x);}}}$xw = new Person();unset($xw->x);
这个时候私有属性就被删除了,在执行unset的时候,由于类外部是无法访问到私有属性,那么 __unset()🈶️检测到要删除私有属性,那么就可以在类的内部执行unset方法,这样才可以删除私有属性。
