Reputation: 6068
I'm pretty new to PHP and am trying to understand how to access properties of objects.
I have a class called Dog
and in it's class I have the following:
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
)
)
}
Now I'm trying to use this data in a controller.
$drm = DogResouceModel::create();
$fido = array_values($drm->find($dog_id))[0];
This works and I get the desired Dog
object as $fido
. How would I get to the owner_id
? Using XDebug in Eclipse I can see that the values are all attached to $fido
, I just can't seem to figure out how to get to them. I've tried things along the lines of:
$owner_id = $fido["_data"]["owner_id"];
$owner_id = $fido->_data->owner_id;
Upvotes: 1
Views: 106
Reputation: 76395
The common way to do this is to implement getter/setter methods:
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;
}
}
The rational behind this is that getters and setters allow you to validate data, normalize it and define, in greater levels of detail, how an object should behave if, for example, a value isn't available (ie: if owner_id is null, you might want to throw an exception in some cases).
The fact that you can see them in an XDebug session is simply because the data is set, and XDebug allows you to inspect the state of all objects. It doesn't follow the rules of inheritance in that it can see all values that are in play, regardless of them being private, protected or public. Xdebug is a PHP extension, it's written in C and sits on top of the Zend engine (the PHP internals), it is not bound by the syntax, grammar or whatever else that is part of PHP.
Think of Xdebug as an MRI scanner or X-ray machine: it allows you to see what is going on underneath the skin. It's a tool doctors use, like debuggers are tools that developers use to diagnose problems.
Looking at what you've tried, even if $data
were public, neither approach would've worked:
$owner_id = $fido["_data"]["owner_id"];
The problem here is that this plies that $fido
is an array, or an object that implements the ArrayAccess
interface. We don't know what Resource
looks like, so maybe it does (more on that later).
$owner_id = $fido->_data->owner_id;
This is closer to what you could do if _data
were public, but only if its value were an object, too (which it isn't, it's an array).
So what should you write if $_data
were public? Well simply this:
$ownerId = $fido->_data['owner_id']['value'];//to get the value
$ownerIdArray = $fido->_data['owner_id'];//will be an array
If Resource
implements the ArrayAccess
interface, chances are it relies on the $_data
property, and returns the values for each key. In that case you might be able to write:
$ownerId = $fido['owner_id']
or even iterate over the object:
foreach ($fido as $propery => $value) {
//do stuff
}
Check the PHP documentation for details on the ArrayAccess
interface
Upvotes: 3
Reputation:
OOP Programming PHP
You are using OOP, grats dude (or dudette :P)!
PHP is great for this, however it has it's limitations, for example, accessing properties.
You have used protected $_data = array( /* your info */ );
, this means it is only visible to the class and any class that extends
this.
For example, if you had these classes:
class Foo
{
protected $foo = "Foo";
}
class Bar extends Foo
{
private $bar = "bar";
}
You could add a function, as such:
public function getFooBar()
{
return "{$this->foo} {$this->bar}";
}
Inside the Bar
class, that simply returns the value of $foo
and $bar
, meaning if you use this code:
$bar = new Bar();
print $bar->getFooBar(); // prints "Foo bar"
But you cannot do this:
print $bar->foo;
print $bar->bar;
These are seen as private
properties of the Bar
class and as such cannot be accessed outside of the class.
When you use protected
or private
properties, if you need to access them outside the class, create a get function for them.
Why does the debugger show the private and protected properties?
When using a debugger such as XDebug, it is designed to show all properties within an object, this is so that the person debugging (you), can see exactly what's in an object and be able to create some sort of functionality to access this if needed. Without this, debugging tools would be rather useless.
I hope this helps you out :P
Upvotes: 1
Reputation: 5668
Because _data
is protected, it's not possible to directly access it from outside the Dog
or Resource
classes. Instead, you should add an accessor to either Dog
or Resource
(as appropriate) that retrieves the requested data.
class Dog extends Resource {
public function getOwerId() {
return $this->_data['owner_id']['value'];
}
}
You could also force _data
to be accessible by hacking it using the Reflection API, but that's really not something you should be doing on production code.
Upvotes: 1