If you create a function that will only be used from an object context (i.e. you want a dynamic method that can then call methods from the original object, still maintaining access to the object's runtime values) then you can use the following functions I have created (ob_lambda_func and ob_lambda) to enable the dynamic function to easily call *public* methods on the object, in their runtime contexts:



<?php

if(! function_exists ( 'ob_lambda_func' )){

function ob_lambda_func ( $method , $args ) {

if(( phpversion ()+ 0 )< 5.1 || ( substr ( phpversion (), 2 )+ 0 )< 1.1 )

die( "

Error: This script requires PHP v5.1.1+!

" );

$bt = debug_backtrace ();

foreach( $bt as $xsp ) {

if(isset( $xsp [ 'object' ])) {

if(! method_exists ( $xsp [ 'object' ], $method )) continue;

return call_user_func_array (array( $xsp [ 'object' ], $method ), $args );

}

}

if(! function_exists ( $method ))

die( "

OB: Internal Error! ( $method )" );

return call_user_func_array ( $method , $args );

}}

if(! function_exists ( 'ob_lambda' )){

function ob_lambda ( $method ) {

return create_function ( '' , '$args=func_get_args(); return ob_lambda_func(' . var_export ( $method , true ). ',$args);' );

}}



class Foo {

private $bar , $baz , $test ;

private $runtimeValue = 0 ;

function __construct () {

$this -> runtimeValue = rand ();

$this -> bar = ob_lambda ( 'Bar' );

$this -> baz = ob_lambda ( 'Baz' );

$this -> test = create_function (

'$bar, $baz' ,

'$bar("Hello, World!"); $baz();'

);

}

function Test () {

$fn = $this -> test ;

$fn ( $this -> bar , $this -> baz );

}

function Bar ( $a ) {

echo " $a : Bar ( $this -> runtimeValue )

" ;

}

function Baz () {

echo "and another! Baz ( $this -> runtimeValue )

" ;

}

}



$foo =new Foo ();

$foo -> Test ();



?>



This snippet (with test) shows how the lambda function $foo->test can call Foo::Bar and Foo::Baz without an explicit reference to the original object. The methods are run from their object context, and so can access the runtime-modified variable $foo->runtimeValue, which is set to a random number on construction.

The function definition for $foo->test is the following:

function ($bar, $baz) {

$bar("Hello, World!");

$baz;

}

As you can see, it is clean and simple, with no obvious artifacts from the use of OB Lambda



The expected output should be:

Hello, World!: Bar (440048505)

and another! Baz (440048505)



Or any other random number in place of 440048505

Make sure, before you change your code, that your target server has PHP 5.1.1+, or these functions won't work and will return an error!

Hope this helps anyone as much as it has me! :)