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


Getting protected information from an object in PHP

我是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; 

执行此操作的常用方法是实现 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 文档以获取有关ArrayAccess接口的详细信息

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

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

你也可以通过使用反射API来强制访问_data,但这真的不是你应该在生产代码上做的事情。

OOP Programming 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;

这些被视为Bar类的private属性,因此不能在类外部访问。

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

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

使用XDebug等调试器时,它旨在显示对象中的所有属性,以便调试人员(您(可以准确查看对象中的内容,并能够创建某种功能来在需要时访问它。没有这个,调试工具将毫无用处。

我希望这对您有所帮助:P