Create_Function() and Recursion

28 12 2010

Test matches are the highest level of major cr...

Image via Wikipedia

One of the best ways to get up to speed with PHP is to read the fine manual that we have online.  But at the same time, one needs to keep some perspective with regard to user comments.  Sometimes those comments are invaluable and provide you with exactly the information you’ve been hard-pressed to find.  Other times, a user may make a comment in such a way that one may jump to the conclusion that the user knows the only correct way and that impression is reinforced if you successfully run the code that the user provides.  Still one should treat user commentary with the same degree of trust that you would have for user supplied data.  By testing and questioning you will become far more knowledgeable than by merely relying on an authoritative sounding comment.

Back in 2006 someone commented on php.net that the only way to properly use create_function() recursively was to pay attention to scope and reference the GLOBAL scope since that is where all dynamic functions reside.  Imagine my surprise when I was able to successfully disregard that advice.  What did I do, you may well wonder.  It’s simple — I paid attention to the formal arguments and what values I was passing to them.

Here’s how I did it:


<?php

$f = create_function('$a,$F', 'echo $a; if ($a < 13) call_user_func($F,  ++$a, $F);');

$f(1,$f);

But it’s more likely that you might use create_function() to create a helper function within a regular user-defined function. Here’s such an example:


function PowerUpFromOne( $num=1, $power=3) {

$str = '';

$str = '';

$f = create_function('$a,$b,$c, $d',  '$c .=  pow($a,$b) . " -  ";

if ( $a < 11 )  {

return call_user_func_array($d, array(++$a,$b,$c, $d) );

}

else {

return $c;

}');

return $f( $num,$power,$str,$f );

}

$r = PowerUpFromOne();

var_dump($r);

Of course these days now that PHP supports lambdas and in particular closures, it might seem silly to even bother with create_function() and its string arguments which support a sort of lambda style.  But, if for some reason you need to use create_function(), you may find this discussion helpful if you wish to avoid using the $GLOBALS array.

Oh, and about where the dynamic “lambda-style functions” reside, it is true that they are in the global namespace which incidentally all PHP functions reside in that space.  This is a convenient feature which allows you to use functions either in the global namespace or even within a function.  Here’s an example that proves where the dynamic functions live:


<?php
function HoHum(){
   echo 'hohum ....
';
}
function Test() {
HoHum();
$f = create_function('', 'echo "Have a Nice Day";');
	return $f;
}
$greeting = Test( );
if ( is_callable($greeting) ) {
echo 'Now invoking $greeting ....<br>';
$greeting();
}

Since create_function returns the name of the dynamic function on success, we can use that name along with a pair of parenthesis to invoke the dynamic function either within another function or else in the global namespace.

This work is licensed under a Creative Commons License
.

Advertisements

Actions

Information

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




%d bloggers like this: