PHP5 Reflection And You


The phpdocs put it kind of weirdly:

PHP 5 comes with a complete reflection API that adds the ability to reverse-engineer classes, interfaces, functions and methods as well as extensions.

I prefer the notorious c.h.x.'s definition

chx: it's like this insane cool weaponset of PHP which is like totally unknown :)

Reflection is a very powerful too that lets you understand the code running in your enviroment. This is particularly important for drupal development, as so much of drupal is based on functions that call functions (e.g. hooks).

The point of this tutorial is to show you how much ass reflection can kick, in so little code. The following page finds out every menu item that calls a function hidden away in a remote file, and gives you the location of the callback function: filepath, and line number and all. Note that the vast majority of code is merely used to output the test table. Obviously, this example merely scratches the surface of useful things you could do with this api.

function apiece_menu() {
$items = array();
$items['test-page'] = array(
'page callback' => 'apiece_page',
'title' => 'reflection-test',
'access arguments' => array('access content'),

apiece_page() {
$header = array("path", "Declared by", 'Callback', "Callback Location");
module_implements('menu') as $hook) {
// get the function by its ball
$func = new ReflectionFunction($hook.'_menu');
// know where it lives
$fun = $func->getStartLine();
// make it talk
if ($results = $func->invoke()) {
$results as  $path => $item) { 
        if (
$item['file']) {
$row = array();
$row[] = $path;
// write down its address...
$row[] = "Line ".$func->getStartLine(). " in ".$func->getFileName();
          if (
function_exists($item['page callback'])) {
$row[] =  $item['page callback'];
// most includes have a module path
$include_path = drupal_get_path('module', $hook);
// but a sneaky few use other modules paths.....
if ($item['file path']) {
$include_path $item['file path'];
// now lets explore this function...
$callback = new ReflectionFunction($item['page callback']);
// same crap
$row[] = "Line ".$callback->getStartLine(). " in ".$callback->getFileName();
$rows[] = $row;
// tables are noobish
return theme('table', $header, $rows);