0

call_user_func_array() makes calling a variable function with a set of arguments fairly simple. I would like to do the same with db_select() passing in various options to different methods. Going to use dblog_cron from 6.x and 7.x as the examples. How can I do something similar in D7?

D6 Code

<?php
// These 2 lines return the same thing in D6
$max = db_result(db_query('SELECT MAX(wid) FROM {watchdog}'));
$max = call_user_func_array('db_result', array(call_user_func_array('db_query', array('SELECT MAX(wid) FROM {watchdog}'))));
?>

D7 Code

<?php
$min_row = db_select('watchdog', 'w')
  ->fields('w', array('wid'))
  ->orderBy('wid', 'DESC')
  ->range(999, 1)
  ->execute()
  ->fetchField();

 // Getting closer but not what I'm looking for.
 $min_row = db_select('watchdog', 'w')
   ->{'fields'}('w', array('wid'))
   ->{'orderBy'}('wid', 'DESC')
   ->{'range'}(999, 1)
   ->{'execute'}()
   ->{'fetchField'}();
?>

How can I call the above code without eval using something like call_user_func_array() or ReflectionMethod::invokeArgs?

  • Why would you want to do this? – Berdir May 1 '12 at 21:30
  • It was a request for how to execute a query directly using HTTPRL's threading library drupal.org/node/1555314 – mikeytown2 May 1 '12 at 21:48
0

Breaking this down...

<?php
$x = call_user_func_array('db_select', array('watchdog', 'w'));
$x = call_user_func_array(array($x, 'fields'), array('w', array('wid')));
$x = call_user_func_array(array($x, 'orderBy'), array('wid', 'DESC'));
$x = call_user_func_array(array($x, 'range'), array(999, 1));
$x = call_user_func_array(array($x, 'execute'), array());
$min_row = call_user_func_array(array($x, 'fetchField'), array());
?>

In-lining everything... so it can be done.

<?php
$min_row = call_user_func_array(array(call_user_func_array(array(call_user_func_array(array(call_user_func_array(array(call_user_func_array(array(call_user_func_array('db_select', array('watchdog', 'w')), 'fields'), array('w', array('wid'))), 'orderBy'), array('wid', 'DESC')), 'range'), array(999, 1)), 'execute'), array()), 'fetchField'), array());
?>

---Solution below---

<?php
// Setup data array.
$args = array(
  array(
    'db_select', array(
      'watchdog', 'w',
    )
  ),
  array(
    'fields', array(
      'w', array('wid')
    )
  ),
  array(
    'orderBy', array(
      'wid', 'DESC'
    )
  ),
  array(
    'range', array(
      999, 1
    )
  ),
  array(
    'execute', array()
  ),
  array(
    'fetchField', array()
  ),
);

// Helper function.
foreach ($args as $data) {
  if (!isset($last)) {
    $last = call_user_func_array($data[0], $data[1]);
  }
  else {
    $last = call_user_func_array(array($last, $data[0]), $data[1]);
  }
}

// Get output
echo $last;
?>

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.