从PHP中的对象获取受保护的信息

时间:2016-02-08 15:42:44

标签: php class object

我是PHP的新手,我正在尝试了解如何访问对象的属性。

我有一个名为Dog的课程,在课堂上我有以下内容:

class Dog extends Resource {
    protected $_data = array(
        'dog_id' => array(
             'type' => Resource::PROPERTY_TYPE_INTEGER, 
             'value' => null
         ), 
         'owner_id' => array(
             'type' => Resource::PROPERTY_TYPE_INTEGER, 
             'value' => null
         )        
    )
}

现在我正在尝试在控制器中使用这些数据。

$drm = DogResouceModel::create(); 
$fido = array_values($drm->find($dog_id))[0]; 

这样可行,我将所需的Dog对象设为$fido。我怎么去owner_id?在Eclipse中使用XDebug我可以看到值都附加到$fido,我似乎无法弄清楚如何找到它们。我尝试过以下方面的事情:

$owner_id = $fido["_data"]["owner_id"];  
$owner_id = $fido->_data->owner_id; 

3 个答案:

答案 0 :(得分:3)

执行此操作的常用方法是实现getter / setter方法:

class Dog extends Resource
{
    protected $data = [];//initialize as before (no need for the underscore)

    public function getOwnerId()
    {
        return $this->data['owner_id']['value'];
    }
    //setter example
    public function setOwnerId($id)
    {
        if (!is_numeric($id)) {
            throw new InvalidArgumentException('Owner id is numeric');
        }
        $this->data['owner_id']['value'] = (int) $id;

        return $this;
    }
}

这背后的理性是,getter和setter允许您验证数据,对其进行规范化并在更详细的细节中定义对象应该如何表现,例如,如果某个值不可用(即:如果owner_id为null,您可能希望在某些情况下抛出异常。)

您可以在XDebug会话中看到它们的原因很简单,因为设置了数据,并且XDebug允许您检查所有对象的状态。它不遵循继承规则,因为它可以看到所有正在运行的值,无论它们是私有的,受保护的还是公共的。 Xdebug是一个PHP扩展,它是用C语言编写的,位于Zend引擎(PHP内部)之上,它不受语法,语法或PHP的其他任何限制。

将Xdebug想象成MRI扫描仪或X光机:它可以让您看到皮肤下面发生了什么。它是医生使用的工具,比如调试器是开发人员用来诊断问题的工具。

看看您尝试过的内容,即使$data 公开,也不会采用任何方法:

$owner_id = $fido["_data"]["owner_id"];  

这里的问题是,$fido是一个数组,或实现ArrayAccess接口的对象。我们不知道Resource看起来是什么样的,也许它确实如此(稍后会详细介绍)。

$owner_id = $fido->_data->owner_id; 

如果_data是公开的,那么这更接近你可以做的事情,但前提是它的值也是一个对象(它不是,它是一个数组)。

那么如果$_data公开,你应该怎么写?简单地说就是这样:

$ownerId = $fido->_data['owner_id']['value'];//to get the value
$ownerIdArray = $fido->_data['owner_id'];//will be an array

如果Resource实现了ArrayAccess接口,则很可能它依赖于$_data属性,并返回每个键的值。在这种情况下,您可以写:

$ownerId = $fido['owner_id']

甚至迭代对象:

foreach ($fido as $propery => $value) {
    //do stuff
}

查看PHP文档以获取有关the ArrayAccess interface

的详细信息

答案 1 :(得分:1)

由于_data受到保护,因此无法从DogResource类外部直接访问它。相反,您应该添加一个访问者DogResource(视情况而定)检索所请求的数据。

class Dog extends Resource {
    public function getOwerId() {
        return $this->_data['owner_id']['value'];
    }
}

您还可以通过使用Reflection API对其进行黑客攻击来强制_data,但

>

答案 2 :(得分:1)

OOP编程PHP

你正在使用OOP,grats dude(或者dudette:P)!

PHP非常适合这种情况,但它有其局限性,例如访问属性 您已使用protected $_data = array( /* your info */ );,这意味着它只对类和extends此类的任何类可见。

例如,如果您有这些类:

class Foo 
{
    protected $foo = "Foo";
}

class Bar extends Foo
{
    private $bar = "bar";
}

你可以添加一个函数,如下:

public function getFooBar()
{
    return "{$this->foo} {$this->bar}";
}

Bar类中,只返回$foo$bar的值,这意味着如果您使用此代码:

$bar = new Bar();
print $bar->getFooBar(); // prints "Foo bar"

但你不能这样做:

print $bar->foo;
print $bar->bar;

这些被视为private类的Bar属性,因此无法在类之外访问。

使用protectedprivate属性时,如果需要在类外部访问它们,请为它们创建一个get函数。

为什么调试器会显示私有属性和受保护属性?

当使用XDebug之类的调试器时,它被设计为显示对象中的所有属性,这样调试的人(你)可以准确地看到对象中的内容并且能够创建一些如果需要,可以访问此类功能。没有它,调试工具将毫无用处。

我希望这可以帮助你:P