我是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;
答案 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
受到保护,因此无法从Dog
或Resource
类外部直接访问它。相反,您应该添加一个访问者Dog
或Resource
(视情况而定)检索所请求的数据。
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
属性,因此无法在类之外访问。
使用protected
或private
属性时,如果需要在类外部访问它们,请为它们创建一个get函数。
为什么调试器会显示私有属性和受保护属性?
当使用XDebug之类的调试器时,它被设计为显示对象中的所有属性,这样调试的人(你)可以准确地看到对象中的内容并且能够创建一些如果需要,可以访问此类功能。没有它,调试工具将毫无用处。
我希望这可以帮助你:P