#权限修饰符
- 权限修饰符的定义:简单来说,他就是用来定义类的成员(属性、方法)的可作用范围,也就是作用域,修饰符的不同,决定了,这个变量可以在哪些作用域下被访问到,乃至对变量进行操作;
- 用来修饰类成员(类成员一般包含,类的属性、类的方法)的访问权限。
##PHP中的修饰符:
- public (公共的)
- protected (受保护的)
- private (私有的)
此文仅记录public 与 private 修饰符属性/方法,protected见【继承篇】
##属性的访问位置
- public 属性/方法,在任意位置都可以访问,无论是在类的内部,还是在类实例上访问,都是可读可写的;
- private 属性/方法,只能在类中进行访问,只在类中进行读写;
示例:
class Ren{
public $name = '小明';
private $money = 20;
public function shuchu($a){
var_dump($a);
var_dump($this->money);
}
}
$a = new Ren();
$a->shuchu('努力!奋斗!加油!');
var_dump($a->money);//Fatal error
- 私有属性和方法,只能在类中使用,类的函数也是一样,在类的实例上不能直接调用类的私有函数,只能通过别的函数,间接调用类内的私有函数;这就极大的方便了封装;
##一个BUG
- 先看代码:
class Ren{
public $name = '小明';
private $money = 20;
public function getMoney($a){
echo $a->money;
}
public function setMoney($a){
$a->money -= 4;
}
}
$a = new Ren();
$b = new Ren();
$b->getMoney($b);
$a->setMoney($b);
$b->getMoney($b);
-
我实例化了两个实例,这个BUG就是,类中的私有属性确实是私有的,但是通过实例化之后的实例,却可以相互影响对方的私有属性,这肯定是不合理的,我走大马路上,我能凭空让人家的钱消失吗,我们都是人类这个对象下的实例,我不应该,也不能,更是不合理的去随意修改别人通过劳动的来的金钱;
-
这个BUG产生的原因是,PHP在实现私有属性这个特性上,不是以实例对象为单位来进行权限的控制,而是以类为单位进行权限的控制;
-
PHP这样设计的理由是:因为类只声明一次,而实例则是不确定声明次数,以类为单位,简化了判断模型,提高语言性能;
-
PHP的内核zend引擎,他的判断是:调用者的类与执行上下文的类是否一致,一致就允许操作。 a->setMoney()这个函数也是在Ren类中,所以可以修改,以类内类外为界限来判断操作是否可行;
-
java,c#也存在这个问题,语言设计之初都是以类为单位进行属性和方法的权限控制;
-
问题是确实存在的,但是在代码的风格上,这种写法也是不推荐的,不应该这么些代码,但是BUG确实存在…