为什么当扩展类时,PHP的私有变量变为公共的

19 浏览
0 Comments

为什么当扩展类时,PHP的私有变量变为公共的

我创建了以下类

PHP版本5.5

abstract class Model
{
    var $id;
    private $cName;
    private $tName;
    public function __construct($id = 0)
    {
        $this->cName = '我是cName';
        $this->tName = '我是tName';            
    }
}

然后是一个扩展类

class claseExtend extends Model
{
    var $id;
    public function hola()
    {
        $this->id = 1;
        return (array) $this;
    }
}

如果我执行以下代码:

$obj = new claseExtend() ;
$retHola =$obj->hola();
print_r($retHola);

我期望得到:array(id => 1)

但输出却是:array( \u0000Model\u0000cName: => '我是cName',

\u0000Model\u0000tName => '我是tName')

我做错了什么,或者为什么私有属性会被包括在数组转换中?

谢谢你的帮助。

0
0 Comments

PHP中的私有变量在继承类时变为公共的是因为print_r函数的特殊性。print_r是一种用于显示类的调试实用函数,可以显示包括私有和受保护的属性。根据PHP手册的描述,print_r、var_dump和var_export函数也会显示PHP 5中对象的受保护和私有属性,但不会显示静态类成员。

在PHP中,私有属性是会在派生类中继承的,但是它们是不可访问的。奇怪的是,如果将print_r替换为return,返回的结果是相同的。

但是,他并没有在对象上使用print_r()函数,而是使用(array)$this将对象转换为数组,并打印这个数组。问题是为什么类型转换包括了私有属性。

解决方法是在派生类中使用protected修饰符来修饰属性,这样就可以在派生类中访问这些属性,但是在类外部仍然是不可访问的。下面是修改后的代码示例:

class ParentClass {
    private $privateVariable = "Private Variable";
    protected function printPrivateVariable() {
        echo $this->privateVariable;
    }
}
class ChildClass extends ParentClass {
    public function accessParentPrivateVariable() {
        $this->printPrivateVariable();
    }
}
$child = new ChildClass();
$child->accessParentPrivateVariable(); // Output: Private Variable

在这个示例中,通过在ParentClass中使用protected修饰符来修饰privateVariable属性,然后在ChildClass中可以通过调用printPrivateVariable方法来访问这个属性。但是在类外部仍然无法访问privateVariable属性。

0
0 Comments

当你将对象转换为数组时,私有和受保护的属性会包含在结果中。文档中提到:

如果将对象转换为数组,结果将是一个数组,其元素为对象的属性。键是成员变量的名称,有一些特殊情况:整数属性是不可访问的;私有变量的变量名前面加上类名;受保护的变量的变量名前面加上“*”。这些添加的值两边都有空字节。

这些空字节在你的结果中显示为\u0000

感谢你的回答,我不明白为什么私有成员可以被这样访问。

它们被赋予了非常奇怪的名称,所以很难无意中访问它们。

出现这个问题的原因是PHP在将对象转换为数组时,为了保持对象的封装性,将私有变量的名称前面添加了类名作为前缀。这样做的目的是为了避免意外访问私有变量。私有变量的名称被修改后,就变得非常奇怪,使得无法直接访问到它们。

然而,虽然私有变量的名称被修改,但它们的值仍然可以通过类的方法进行访问。这样做的好处是可以保护对象的封装性,防止外部代码直接访问私有变量,从而避免意外修改对象的状态。

解决这个问题的方法是在子类中使用父类的方法来访问私有变量。由于父类的方法可以访问它的私有变量,因此可以通过在子类中调用父类方法的方式来获取私有变量的值。

总之,尽管PHP在将对象转换为数组时会将私有变量的名称进行修改,但这种修改仅仅是为了保护对象的封装性,防止意外访问和修改私有变量的值。通过使用父类的方法来访问私有变量,可以解决这个问题。这样做既能保护对象的封装性,又能获取私有变量的值。

0