封装性是对面对象的三大特性之一,封装就是把对象中的成员属性和成员方法加上访问修饰符,使其隐藏对象内部的细节,达到对成员访问的控制(并非拒绝访问)。

3种修饰符

  • public (公有的 默认)
  • private (私有的)
  • protect (受保护的)

4种魔术方法

  • __set()
  • __get()
  • __isset()
  • __unset()

    私有成员的设置与访问

    封装后的私有成员是外部不能直接访问的,只有通过对象内部方法种的 $this 访问。
  1. <?php
  2. class Person
  3. {
  4. public $name = "zhijia"; // 公有的
  5. private $age = 27; // 私有的
  6. protected $money = 10; // 受保护的
  7. private function getAge()
  8. {
  9. // 私有的成员方法 不能在类的外部访问
  10. return $this->age;
  11. }
  12. protected function getMoney()
  13. {
  14. // 被保护的成员方法 不能在类的外部访问
  15. return $this->money;
  16. }
  17. public function card()
  18. {
  19. echo $this->getName().$this->getMoney();
  20. }
  21. }
  22. $xw = new Person();
  23. echo $xw->age;
  24. echo $xw->money;
  25. echo $xw->getAge();
  26. echo $xw->getMoney();

上面代码会输出 没有权限访问 age、money、getAge()、getMoney();这里如果访问card() 那么就会正常输出moeny、age的值。

__set()

  1. <?php
  2. class Person
  3. {
  4. private $name = "zhijia"; // 私有的
  5. private $age = 27; // 私有的
  6. protected $money = 10; // 受保护的
  7. private function getAge()
  8. {
  9. // 私有的成员方法 不能在类的外部访问
  10. return $this->age;
  11. }
  12. protected function getMoney()
  13. {
  14. // 被保护的成员方法 不能在类的外部访问
  15. return $this->money;
  16. }
  17. public function card()
  18. {
  19. echo $this->name.$this->getAge().$this->getMoney();
  20. }
  21. public function __set($key, $value)
  22. {
  23. // 数据劫持 两个参数 一个是属性名 一个是对应的值
  24. // 并且该方法只针对 private 私有的属性 和 protected 受保护的属性有效
  25. if($key == "name" && $value == "laowang"){
  26. $this->name = "xiaowang";
  27. }
  28. }
  29. }
  30. $xw = new Person();
  31. $xw->name = "laowang";
  32. $xw->card();


这样name就变成了”xiaowang”,通过修改私有属性,可以触发 __set 方法。这样我们就可以做到数据的劫持。

__get()

  1. <?php
  2. class Person
  3. {
  4. private $name = "zhijia"; // 私有的
  5. private $age = 27; // 私有的
  6. protected $money = 10; // 受保护的
  7. public function __get($key)
  8. {
  9. // 数据劫持 参数是属性名
  10. // 并且该方法只针对 private 私有的属性 和 protected 受保护的属性有效
  11. if ($key == "age") {
  12. return "girl not tell you";
  13. }
  14. }
  15. }
  16. $xw = new Person();
  17. echo $xw->age;

这里我们就可以看到输出了 “gril not tell you”,因为访问私有属性的时候被数据被劫持了。并给我们返回了一句话。

__isset()

  1. <?php
  2. class Person
  3. {
  4. private $x = 123;
  5. public function __isset($key)
  6. {
  7. if($key == "x"){
  8. return true;
  9. }
  10. }
  11. }
  12. $xw = new Person();
  13. var_dump(isset($xw->x));


页面输出boole(true)。iseet方法会检查类里面有没有这个私有属性,如果不通过数据劫持,那么因为是私有属性会永远输出false。毕竟私有属性是不允许在类外部访问的。

__unset()

  1. <?php
  2. class Person
  3. {
  4. private $x = 123;
  5. public function __unset($key)
  6. {
  7. if($key == "x"){
  8. unset($this->x);
  9. }
  10. }
  11. }
  12. $xw = new Person();
  13. unset($xw->x);


这个时候私有属性就被删除了,在执行unset的时候,由于类外部是无法访问到私有属性,那么 __unset()🈶️检测到要删除私有属性,那么就可以在类的内部执行unset方法,这样才可以删除私有属性。