tags:

views:

57

answers:

2

This question is similar to this one but (literally) takes it to another level, or levels.

Background: I am using the Kohana PHP framework and, specifically, the ORM library.

Basically, when you loop through DB results with it, you can access the field values as properties of an object. Any joined tables can be accessed in a hierarchical manner. For example:

$users = ORM::factory('user')->with('city')->with('city:country')->find_all();
foreach ($users as $user) {
    echo "<p>{$user->name} ({$user->city->name}, {$user->city->country->name})</p>";
}

will output:

User 1 (City 1, Country 1)

User 2 (City 2, Country 1)

User 3 (City 2, Country 1)

User 4 (City 3, Country 2)

User 5 (City 4, Country 2)

etc.

Now, my question is: is there a way to access the hierarchical properties of an object for any number of levels. Ideally, I would like to do something like this:

$users = ORM::factory('user')->with('city')->with('city:country')->find_all();
$var2 = 'name';
$var2 = 'city->name';
$var3 = 'city->country->name';
foreach ($users as $user) {
    echo "<p>" . $user->{$var1} . "(" . $user->{$var2} . ", " . $user->{$var3} . ")</p>";
}

Is this possible in some simple way that I am missing?

Many thanks!

A: 

OK, I've cracked this.

I've written a function like so:

public static function get_attribute($object, $level)
{
    $level = explode('->', $level);
    if (count($level) == 1) {
        return $object->{$level[0]};
    } else {
        $object = $object->{$level[0]};
        unset($level[0]);
        return self::get_attribute($object, implode('->', $level));
    }
}

God bless recursion.

meanstreakuk
And if anyone has a better answer than this, I'd be more than happy to accept it.
meanstreakuk
A: 

Try this:

$users = ORM::factory('user')->with('city')->with('city:country')->find_all();
$var1 = 'name';
$var2 = 'city.name';
$var3 = 'city.country.name';
foreach ($users as $user) {
    $user = $user->as_array();
    echo "<p>" . Arr::path($user, $var1)  . "(" . Arr::path($user, $var2) . ", " . Arr::path($user, $var3) . ")</p>";
}

To understand what Arr:path does (taken from Kohana's documentation):

// Get the value of $array['foo']['bar']
$value = Arr::path($array, 'foo.bar');

EDIT:

The above solution is for Kohana v3. For Kohana 2.3.4, see the third post on this page.

dusan
Sorry I should have specified I'm using Kohana 2.3.4 - this function appears to be Kohana 3 only.That said, it is a good solution and one I would definitely use if I were using Kohana 3.
meanstreakuk
Ok, I edited the answer to clarify that.
dusan