I/O Reader

RSS Feed

Peter Goodman's blog about PHP, Javascript, Functional Programming, Applications, Actionscript,

Hacking Variable Composition: Another Approach to PHP Lambdas

posted on Jun 18, 2007 at 8:55pm with eight comments and tagged with PHP, Functional Programming

I was fooling around with variable composition today and had a cool idea. Before that, if you don't know what variable composition is then here are some examples of the neat manipulations PHP lets you do with variables.


// variable variables
$foo = 'bar';
$bar = 'hello';

echo $$foo; // outputs: 'hello'

// variable composition
$foo = 'bar';

echo ${'foo'}; // outputs: 'bar'

Essentially it is just different syntax for variables. However, with the right techniques, we can make it into so much more. For example, here is a composed variable that will actually execute a database UPDATE query:

<pre lang="php">
// fake db query
function db_query($sql) {
    // do query here...
    echo $sql;
}

function query_error_handler($error_num, $error_str, $error_file, $error_line) {
    if($error_num == 8 && preg_match("~^Undefined variable: update~i", $error_str)) {
        return db_query(str_ireplace('Undefined variable: ', '', $error_str));
    }
    return FALSE;
}

set_error_handler('query_error_handler');

// perform a db query
!${"UPDATE mytable SET foo='bar'"};

You should be able to determine just from looking at this that you shouldn't use this type of hack in production code. Otherwise, for the curious programmer, it's definitely an interesting line to pursue. Now, on to Lambdas. My last article on closures/lambdas fixed a few bugs in my system and cleaned up the code; however, there was still the annoying of having to used ->call() to call the function. Essentially, I want to be able to do: lambda(...)(arg1[, arg1[, arg3[, ....]]]). Unfortunately this cannot be done. However, it can be approximated with variable composition. Check this out:

$lambda_1;

function lambda($args = '', $content = '') {

    global $lambda_1;

    $lambda_1 = create_function($args, $content);

    return 'lambda_1';
}

echo ${lambda('$a', 'return $a;')}('hello world');

// output: 'hello world'

Clearly this code was set up specifically for this example, however I definitely think that this can be built on.

Comments


Comment



write down what you see in the box below (all uppercase)