Getting Multiple Object Fields -- FAST

A very fast way to retrieve selected object fields without getting the whole object


In some previous articles, we discussed a fast way to get individual object fields in MODX Revolution with getValue(), but what if you need more than one field?

In this article, we'll look at a very fast way to get multiple object fields and place them in a PHP array without retrieving the whole object.

 

The Method

This is an example that gets several resource fields from the resource with the ID 12:

$query = $modx->newQuery('modResource');
$query->where(array('id' => '12'));
$query->select(array(
    'ID'        => 'id',
    'Class'     => 'class_key',
    'Context'   => 'context_key',
    'Published' => 'published'
));
$results = array();
if ($query->prepare() && $query->stmt->execute()) {
    $results = $query->stmt->fetchAll(PDO::FETCH_ASSOC);
}

echo print_r($results, true);

 

The code above will display something like this:

Array
(
    [0] => Array
        (
            [ID] => 12
            [Class] => modDocument
            [Context] => web
            [Published] => 1
        )
)

 

Note that the terms on the left side of the select() array are arbitrary "aliases". You're free to use the actual field names, but whatever you use will provide the keys for the $results array. That allows you to use them as captions in the output instead of the actual field names, as in the example below. The values on the right must be the actual field names.

 

Things to Remember

In order to use this method, you need to know the actual names of the fields you need. You can find the available fields for each MODX object here.

As we saw in the previous article, the results will be in a nested array, even if there's only one result. It will be an array where each member is an array of 'fieldname' => 'value' pairs representing one row of the table. If we had used the code below for the where clause, we'd get many results, each nested under the larger array:

$query->where(array(
    'published' => '1',
));

 

You also need to remember that, just like in the previous article, you will be getting the raw field values because the data is not being passed through the xPDO get() method. Date fields will be in the form of Unix timestamps and fields like the modUser object's extended field and the properties field for resources and elements will be returns as JSON strings. If you are getting a TV values, you'll also get the raw, un-rendered values, which might be @INHERIT for example.

 

Walking

Because we created our own array keys in the code above, we can walk through and display the array with nested foreach loops, like this:

foreach ($results as $result) {
    foreach ($result as $key => $value) {
        echo "\n<br/>" . $key . ': ' . $value;
    }
}

The output of that code for each object would look something like this:

<br />ID: 12
<br />Class: modDocument
<br />Context: web
<br />Published: 1

 

This double foreach loop will only work if you can display the raw field values without processing any of them.

 

Using Tpl Chunks

Rather than the double foreach loop shown above (which usually isn't very practical), you can use a Tpl chunk with placeholder tags to format the data, and still have very fast page-load times. Using our example query above, here's an example using a simple Tpl Chunk.

 

MyChunk Tpl Chunk

<p>ID: [[+ID]]</p>
<p>Class: [[+Class]]</p>
<p>Context: [[+Context]]</p>
<p>Publisher: [[+Published]]</p>
<p>&nbsp;</p>

 

The PHP Code

$output = '';
foreach ($results as $result) {
    $output .= $modx->getChunk('MyChunk', $result);
}
return $output;

 

At first glance, this looks like the standard way to process results using the Tpl chunk, but it's not. Notice that the placeholders are not the actual field names — they are the "captions" (more correctly, the "aliases") from the *left* side of the $query->select()array we used above to get the data. In the standard Tpl chunk usage, we call toArray() on the objects and the actual field names are the "keys" of the resulting array. In this case, we were able to create our own aliases in the select() call.

That said, it's usually a good idea to use the actual field names (assuming that you know them) for both the select() call and for the placeholders just so that, when entering the placeholders, you don't have to remember exactly what aliases you used. If you already have the Tpl chunks and are converting to this method, you'll definitely want to use the actual field names for the aliases — that way the Tpl chunk won't need to be changed.

 

For more information on how to use MODX to create a web site, see my web site Bob's Guides, or better yet, buy my book: MODX: The Official Guide.

Looking for quality MODX Web Hosting? Look no further than Arvixe Web Hosting!



Comments (2)

  1. adam enthovenNov 27, 2014 at 12:29 AM

    Hi Bob,
    Great article. I enjoy reading your tips very much.
    If speed is an issue, as the title suggests, is $modx->getchunk() then the right choice?

    $chunk = $modx->getObject('modChunk', array('name' => 'mychunk'));
    $chunk->process(array( 'class' => $MyClass, 'id' => 'ID'));
    is faster. At least is was once maybe that changed in 2.3?
    RDG

  2. Bob RayJul 03, 2015 at 10:46 PM

    Sorry, I missed your comment when it was posted.

    I'd be surprised if that was much faster, since getChunk() does essentially the same thing.


Please login to comment.

  (Login)