There is no simple, built-in way (that anyone seems to have found) to pass additional arguments to a callback function in PHP. There are various ways to work around the problem.

This work-around preserves the necessary args prior to invoking your callback function, and retrieves them once your are inside the callback function.

If you are already working inside an object…

class MyClass {
    private arCallbackArgs = null;

    ////////////////////////////////////////////////
    //To pass arguments to a callback function:
    // - set them somewhere prior to calling the callback function
    // - retrieve them once you are inside the callback function
    // This pair of private functions makes this possible
    private function setCallbackArgs( $arArgs )
    {
        //blanks out any previously-stored args each time we are called
        //requires an array of args passed all at once, not individual args
        $this->arCallbackArgs = ( is_array( $arArgs ) ? $arArgs : array() );
    }
    private function getCallbackArg( $szArgName )
    {
        //retrive a single arg if set, empty string if not
        return ( ( is_array( $this->arCallbackArgs ) && isset( $this->arCallbackArgs[ $szArgName ] ) )
                    ? $this->arCallbackArgs[ $szArgName ] : '' );
    }

    ////////////////////////////////////////////////
    //an object method that invokes a callback function
    private function myWorkerFunction( $param1, $param2 )
    {
        //specify your callback function
        // for explanation, see: http://www.php.net/manual/en/function.call-user-func.php
        //could be:
        //  $CallbackFunc = 'function_name';                     //NOT USEFUL HERE
        //  $CallbackFunc = array( 'classname', 'methodname' )   //for static methods
        //  $CallbackFunc = array( &$objInstance, 'methodname' ) //for instantiated objects

        //indicates that your callback function is "$this->myCallbackFunction()"
        $CallbackFunc = array( &$this, 'myCallbackFunction' );

        //preserve $param1 and $param2 for later retrieval
        // you could preserve anything, including arrays
        $this->setCallbackArgs( array( 'param1' => $param1, 'param2' => $param2 ) );

        //an equivalent way to create an array like the one above is to use "compact()"
        // "compact()" returns an array of key=>value pairs from specified variable names in our scope
        // see: http://us2.php.net/manual/en/function.compact.php
        $this->setCallbackArgs( compact( 'param1', 'param2' ) );
    
        //do the thing that requires your callback function
        // - could be anything that uses a callback function (this is just one example)
        $results = preg_replace_callback( '#mypattern#',      //just an example
                                          $CallbackFunc,      //see above
                                          "some string" );    //just an example

        //... do other work ...
    }

    ////////////////////////////////////////////////
    // preg_replace_callback automatically sends
    // array of matches to its callback function
    private function myCallbackFunction( $arMatches )
    {
        //retrieve your preserved parameters
        $param1 = $this->getCallbackArgs( 'param1' );
        $param2 = $this->getCallbackArgs( 'param2' );

        //... do other work ...
    }
}

Of course, if you are NOT working within an existing object, you can still use a similar approach. I have condensed it into a single function that behaves differently depending on the “type” (array vs string) of its single $arg…

////////////////////////////////////////////////
// Single non-object function to preserve and
//  retrieve additional parameters for callback functions
// Does not use "globals" but rather a local "static"
//  - remember, statics are preserved after function exits
//    making them available next time function is reached
//
// Usage:
//  if "$arg" is an array, preserve it (return nothing)
//  if "$arg" is a string, return that element of
//   earlier-preserved array (if set, empty string if not)
function callbackArgs( $arg )
{
    static $arCallbackArgs = null;
    if( is_array( $arg ) ) { $arCallbackArgs = $arg; }

    else return ( is_string( $arg ) && 
                  is_array( $arCallbackArgs ) &&
                  isset( $arCallbackArgs[ $arg ] ) )
                    ? $arCallbackArgs[ $arg ] : '' );
}

////////////////////////////////////////////////
//a non-object method (regular function) that
// invokes a callback function
function myWorkerFunction( $param1, $param2 )
{
    //specify your callback function
    //  $CallbackFunc = 'function_name';
    //indicates that your callback function is "myCallbackFunction()"
    $CallbackFunc = 'myCallbackFunction';

    //preserve $param1 and $param2 for later retrieval
    callbackArgs( compact( 'param1', 'param2' ) );

    //do the thing that requires your callback function
    // - could be anything that uses a callback function (this is just one example)
    $results = preg_replace_callback( '#mypattern#',      //just an example
                                      $CallbackFunc,      //see above
                                      "some string" );    //just an example

    //... do other work ...
}

////////////////////////////////////////////////
// preg_replace_callback automatically sends
// array of matches to its callback function
function myCallbackFunction( $arMatches )
{
    //retrieve your preserved parameters
    $param1 = callbackArgs( 'param1' );
    $param2 = callbackArgs( 'param2' );

    //... do other work ...
}

Enjoy

Page Visits: 4880 visits since 17 August 2011
Last Visited: 23 October 2020 at 7:24pm