php权限控制

权限修饰符
作用: 用来说明 属性/方法的权限特点
写在 属性/方法前面

共有3个权限修饰符
private 私有的 , 保护的最严
protected 保护的
public 公共的 ,保护的最松

疑问:
public修饰的属性/方法,可以在哪儿访问?private 修饰的属性/方法,可以在哪儿访问?

如何判断属性/方法 有没有权限访问?
答:看访问时的位置!

private的属性/方法,只能在类定义的大括号内{},才能访问
public 的属性, 在任意位置都可以访问

class Human {
    public $mood = ''; // 心情,公有
    private $money = 1000; // 钱,私有

    public function showMoney() {
        return $this->money;
    }

    private function secret() {
        echo '我小时候偷吃过一块肉';
    }

    public function tellMe() {
        $this->secret();
    }
}
$lisi = new Human();

$lisi->mood = 'happy';
echo $lisi->mood,'<br />'; // happy;

$lisi->money = 500; // 调用位置在Human类的{}外面 ,因此,调用失败
echo $lisi->money; // 调用位置在Human类的{}外面 ,因此,调用失败

echo $lisi->showMoney(),'<br />'; //showMoney是公共的,在此行可以调用,return $this->money; 这一句运行的环境是在 类的{}内部,因此有权限访问 money属性。
$lisi->secret();   // 不可以
$lisi->tellMe();    // 可以,因为是通过$this->secret();调用,即类内调用的.

总结: private权限控制,只能在类的{} 内调用,走出了{}, 谁也调不动.

权限控制的bug

class Human {
    private $money = 1000;

    public function getMoney($people) {
        return $people->money;
    }

    public function setMoney($people) {
        $people->money -= 500;
    }

}

$zhangsan = new Human();
$lisi = new Human(); 

// echo $lisi->money; // 不行

// 让李四去打探张三的钱
echo $lisi->getMoney($zhangsan),'<br />';

// 让李四去改变张三的钱
$lisi->setMoney($zhangsan);
echo $lisi->getMoney($zhangsan),'<br />';

print_r($zhangsan);

/**
奇怪之处在于, 
zhangsan的钱,应该有zhangsan来调用getMoney和setMoney才能影响.

但是和我们前一页面所写的原则是符合的:
即:
调用 getMoney,public,有权.
getMoney() 又在类的{}内,有权读取私有属性money

调用setMoney,public 有权
setMoney()修改zhangsan的money,发生在类的{}内,有权操作

十八哥的总结
李四读取和改变张三的钱,这如果从生活角度来看,是不合理的

钱私有,是指 “每个对象的钱,针对每个对象私有”;即:张三的钱,由张三->showMoney才能引用.

李四不应该有权直接引用,或者说,李四->showMoney,也只有权引用李四自己的money属性.

但是,在上面的代码中,李四却显然引用和改为张三的钱.
这是因为:
PHP在实现上,并不是以对象为单位来控制的权限.而是以类为单位,来控制的权限,所以前一页,不断强调 ,类内,类外,而不是说对象内,对象外.

因为 类声明一次,而对象却可能非常多.以类为单位,简化了判断模型.

第三,从代码的来看
zend引擎
ce==EG(scope)
这一句判断的是
调用者属性的类 与 执行上下文所属的类 是否相等

在我们判断中:
lisi>>Human lisi->setMoney()函数,也在Human类中,
在同一个类内部,可以调用.

这也说明了,确实是以类为单位,以类内类外为界限做的判断

case ZEND_ACC_PRIVATE:
if ((ce==EG(scope) || property_info->ce == EG(scope)) && EG(scope))
{
return 1;
} else {

第四
从其他语言来看一看这个问题.java c#,也存在此问题

第五: 从面向对象的角度来考试
我们的写法,也有问题就不应该把一个对象,直接传给一个方法来使用
而应该 zhangsan borrow钱,应该对应 lisi sent钱
即 应该尽量的来调用对象的方法,而不应该直接把对象当成参数给传过去.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值