Dynamically Access PHP Object Properties with $this

Image
Drupalize.Me Tutorial

I got the opportunity to field this question that was emailed into support today in regards to the video Writing Custom Field Handlers Continued. This video is part of our Coding For Views For Drupal 7 series.

In the file "databasics_handler_field_percent.inc", what does the following notation mean?

$nid = $row->{$this->aliases['nid']};

From what I could gather it roughly means I'm accessing the view object from the row object, but I'm not sure. I could run dsm($row) and dsm($row->{$this->aliases['nid']}), but dsm($row->{$this}) didn't work.

What's the relation between $row and $this? What does $this stand for?

Would you please clarify?
thank you in advance!

It's a great question, and I thought I would answer it with a blog post since I can see how it would be confusing.

First off, is what does $this mean? In Object Oriented PHP, $this is a special "pseudo" variable inside the scope of a method that is part of a class that refers to this particular instance of this class. It's a way of allowing an object to reference itself. For more information on the $this variable check out our video Work with PHP Class Methods around the 2 minute mark.

$nid = $row->{$this->aliases['nid']};

Given this line of code, the objective is to retrieve the $nid value from the $row object. However, in this particular case, we don't know what the name of the property on $row is that contains the value we're after.

Here's a slightly simpler example of a similar thing. Let's say we want to access the $row->my_nid property. We could do it like this:

$nid = $row->my_nid;

Or, alternately, this would achieve the same thing:

$nid_property = 'my_nid';
$nid = $row->{$nid_property};

Using the ->{$nid_property} notation says, evaluate the variable $nid_property, and substitute its value with the name of the property to access. So PHP eventually interprets this as $row->my_nid. The beauty is that $nid_property can be set based on some other logic that determines, through whatever means, what the property name ought to be.

That's exactly what's going on here:

$nid = $row->{$this->aliases['nid']};

When you create a new View with the Views UI, it's possible to add the same field any number of times. Or, to do something like add the node.title field and then add the node.title field of a different node pulled in through a reference. Whenever you add a field to a View the Views module needs to create a unique name for that field to use in the corresponding SQL query. MySQL doesn't like it when you try and select two columns with the same name, so instead you create aliases, and you'll need a way to access the individual values in the PHP representation of the row returned from MySQL. This isn't exactly what Views would produce, but it's close enough to illustrate the problem being solved.


SELECT node1.nid AS node_1_nid, node2.nid AS node_2_nid FROM node node1 LEFT JOIN node node2 ON node2.nid = node1.some_other_field;

When this query is performed by Views the result is stored in the $row variable. The properties match the names of the aliases used in the query, so we have one named "node_1_id" and one named "node_2_nid". Both generated on-the-fly by Views. None named simply "nid". So when you want to retrieve the NID value you need to know the name of the alias. Those are stored by Views in the $this->aliases property of the Views object.

So we end up with this code to get the value of the NID:

$nid = $row->{$this->aliases['nid']};

Which, has the effect of looking up in the $this->aliases array what the value of the nid key is, and then substitutes the resulting value into the $row->{} expression and you end up with something like $nid = $row->node_1_id.

Finally, why does this work dsm($row->{$this->aliases['nid']});, and this dsm($row->{$this}); doesn't? Because the $this variable, which is a representation of the Views object that's used to represent the View currently being built (see above) can't be coerced into a string, and thus there isn't any reasonable value to use as the name of the property you want to access on the $row object.

Resources

Comments

I'm having a class with a static array property, of which I have to change the name everytime an object is created because of, well, static properties and their behavior. I got the changing of the property name down with the curly brackets method, but now I want to know how I can dynamically acces this variable. Any help would be appreciated!

I would think that you could access it the same way, using curly brackets. $myObject->{$my_random_property_name}['array_key'];. Otherwise, I'm not sure I'm following your questions. Some sample code might help to illustrate what you're trying to do.

About us

Drupalize.Me is the best resource for learning Drupal online. We have an extensive library covering multiple versions of Drupal and we are the most accurate and up-to-date Drupal resource. Learn more