1

I have a block module that displays some data taken from XML. That module has multiple (approx. 7) blocks, each of which displays a different "view" of the same XML. Each block can be positioned independently on the page, but all of the blocks are displayed at once and all of the blocks use the same data.

Since the XML parsing code runs inside the block_view() hook, it runs once for every block.

My problem is that the XML parsing is expensive in terms of time (not hugely so, but easily >95% of the total module runtime), and this is a page that I want to run as fast as possible.

How can I move the XML parsing out of the block_view() hook and run it once per page view? Is there another hook that will let me set some global variables or something like that?

function my_module_block_info() {
    $blocks[0]['info'] = t("My Module: block one");
    $blocks[1]['info'] = t("My Module: block two");
    $blocks[2]['info'] = t("My Module: block three");
    ...etc (~7 blocks total)...
    return $blocks;
}

function my_module_block_view($delta = '') {
    $parsed_stuff = parse_some_xml();
    switch ($delta) {
        case 0:
            $block['subject'] = t('Blah');
            $block['content'] = block_0_html($parsed_stuff);
            break;
        case 1:
            $block['subject'] = t('Yada');
            $block['content'] = block_1_html($parsed_stuff);
            break;
        case 2:
            $block['subject'] = t('Etc');
            $block['content'] = block_2_html($parsed_stuff);
            break;
        ...etc (~7 blocks total)...
    }
    return $block;
}
3

You can use static caching in your parse_some_xml function. Some people consider this a cleaner, less evil solution than using global variables (but I will not get into that discussion here).

With static caching, your my_module_block_view() would remain the same, but your parse_some_xml() would look like this:

function parse_some_xml() {
  static $parsed_xml;
  if (!isset($parsed_xml)) {
    // Do the actual parsing here, and store the data in $parsed_xml
  }
  return $parsed_xml;
}

See A Beginners Guide to Caching Data to learn more about static caching.

1

You can use hook_init() to setup a global variable.

function my_module_init() {
  global $parsed_stuff;
  $parsed_stuff = parse_some_xml();
}
  • I can't get the hook_init() to get called (function live_results_init() {die;} does nothing), but the global bit worked - I'm just doing global $parsed_stuff; global $is_cached; if (!$is_cached) { $parsed_stuff = parse_some_xml(); }. It's pretty much dividing my runtime by 7. – George Oct 28 '11 at 4:35
  • 2
    Use static instead of global, see the answer from marcvangend. – Berdir Oct 28 '11 at 9:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.