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