tags:

views:

8457

answers:

10

How are callbacks written in PHP?

+9  A: 

Implementation of a callback is done like so

// This function uses a callback function. 
function doIt($callback) 
{ 
    $data = "this is my data";
    $callback($data); 
} 


// This is a sample callback function for doIt(). 
function myCallback($data) 
{ 
    print 'Data is: ' .  $data .  "\n"; 
} 


// Call doIt() and pass our sample callback function's name. 
doIt('myCallback');

Displays: Data is: this is my data

Nick Stinemates
Oh my god. Is that the standard? That's terrible!
Nick Retallack
There are a few other ways to do it as shown above. I really thought the same.
Nick Stinemates
+2  A: 

That was fast ;) 35 seconds to answer own question :D

I was about to post this solution, But I think you deserve the Shotgun badge ! :)

Fernando Barrocal
must of had the answer pre-written i'm guessing
SeanDowney
:) i don't think you get the shotgun badge for answering your own question.
Nick Stinemates
+6  A: 

One nifty trick that I've recently found is to use PHP's create_function() to create an anonymous/lambda function for one-shot use. It's useful for PHP functions like array_map(), preg_replace_callback(), or usort() that use callbacks for custom processing. It looks pretty much like it does an eval() under the covers, but it's still a nice functional-style way to use PHP.

yukondude
Unfortunately, the garbage collector doesn’t play very well with this construct producing potential memory leaks. If you’re out for performance, avoid create_function().
toscho
Ouch. Thanks for the heads-up.
yukondude
+2  A: 

I cringe every time I use create_function() in php.

Parameters are a coma separated string, the whole function body in a string... Argh... I think they could not have made it uglier even if they tried.

Unfortunately, it is the only choice when creating a named function is not worth the trouble.

Pat
And, of course, it's runtime string eval, so it doesn't get checked for valid syntax or anything else at compile time.
hobbs
+3  A: 

well... with 5.3 on the horizon, all will be better, because with 5.3, we'll get closures and with them anonymous functions

http://wiki.php.net/rfc/closures

pilif
+2  A: 

I would also add a check to see if the function exists:

function doIt($callback) {
    if(function_exists($callback)) {
        $callback();
    } else {
        // some error handling
    }
}
SeanDowney
What if callback is not a function, but an array holding object and method?
sims
+34  A: 

PHP callbacks are structures that "point" to global functions, object methods, or static methods of a class. This allows some level of functional programming in PHP before 5.3. The 3 flavors are:

$cb1 = 'someGlobalFunction';
$cb2 = array(&$obj, 'somePublicMethod');
$cb3 = array('ClassName', 'someStaticMethod');

Here's how you should call a callback function:

if (is_callable($cb3)) {
    // $cb3 is a valid callback, the class "ClassName" is loaded and has
    // a public method "someStaticMethod"

    $ret = call_user_func($cb3, $arg1, $arg2);
    // $ret has the return value of the $cb3.
}

Only the string form can be called by appending parenthesis, but this limits the utility and readability of code:

$ret = $cb1($arg1, $arg2); // OK

$ret = $cb2($arg1, $arg2); // will cause error
$ret = $cb3($arg1, $arg2); // will cause error

See: http://php.net/callback

mrclay
This is vastly better than OP's accepted self-answer.
chaos
Indeed, using the function is the proper way to do it. While using a variable and then just calling it, as suggested in the accepted answer is cool, it's ugly and won't scale well with code.
icco
Changed accepted answer. Agreed with comments, this is a great answer.
Nick Stinemates
+1  A: 

This did not work for me inside a class. I had to use call_user_func.

<?php

class Dispatcher {

    public function Dispatcher( $callback ){
         $this->callback = $callback;
    }

    public function asynchronous_method(){
       //do asynch stuff, like fwrite...then, fire callback.
       if ( isset( $this->callback ) ) {
      if (function_exists( $this->callback ) call_user_func( $this->callback, "File done!" );
     }
    }

}

Then, to use:

<?php 
include_once('Dispatcher.php');
$d = new Dispatcher( 'do_callback' );
$d->asynchronous_method();

function do_callback( $data ){
   print 'Data is: ' .  $data .  "\n";
}
?>
goliatone
A: 

With PHP 5.3, you can now do this:

function doIt($callback) { $callback(); }

doIt(function() {
    // this will be done
});

Finally a nice way to do it. A great addition to PHP, because callbacks are awesome.

Bart van Heukelom