|
|||||||
New to SitePoint Forums? Register here for free!
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 |
|
SitePoint Enthusiast
![]() Join Date: Mar 2005
Posts: 64
|
example of a callback in PHP
I was talking with a friend who does most of his coding in C today and he was mentioning callback functions and said how handy they were. Most definitions on the web seemed pretty vague and most of the code was C code involving pointers. I kinda understood it but was wondering if someone could provide a good example of a callback in PHP.
thanks |
|
|
|
|
|
#2 |
|
SitePoint Author
![]() ![]() ![]() Join Date: Nov 2004
Location: Åsnorrbodarna
Posts: 12,249
|
The xml_set_element_handler function, among others, uses callbacks.
Callbacks work like this: PHP Code:
|
|
|
|
|
|
#3 |
|
SitePoint Zealot
![]() ![]() Join Date: Jul 2004
Location: The Netherlands
Posts: 170
|
|
|
|
|
|
|
#4 |
|
SitePoint Wizard
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Apr 2004
Location: germany
Posts: 4,324
|
callbacks are indeed very handy in procedural programming, but in OOP every call is resolved via pointer and callbacks as such do not make much sense.
PHP Code:
|
|
|
|
|
|
#5 |
|
SitePoint Addict
![]() ![]() ![]() Join Date: Jan 2005
Location: Belgium
Posts: 355
|
Imho, in the OO version this would couple the compare function to $a..
Here is my version ![]() PHP Code:
|
|
|
|
|
|
#6 |
|
Non-Member
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jan 2003
Posts: 5,788
|
Callbacks are much like Delegates, more than anything else, from an object oriented context. Do a search for the Delegate on Google if you want to learn more
![]() |
|
|
|
|
|
#7 |
|
SitePoint Addict
![]() ![]() ![]() Join Date: Jun 2004
Location: Norway - Oslo
Posts: 203
|
A good example of callback is preg_replace_callback , atleast one i've used for complex regexes for text parsing more than once.
|
|
|
|
|
|
#8 |
|
SitePoint Victim
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Apr 2003
Location: London
Posts: 2,385
|
Hi.
The PHP array_map() function is a good one... PHP Code:
You can write your own call back functions, as the function name is usually passed as a string... PHP Code:
PHP Code:
The Observer pattern has a single notify() method rather than a full interface. This is equivalent of the delegate in C# I believe (someone please correct me). The Visitor pattern involves passing the caller itself in as the listener. Say we are using the parser from an RSS reader... PHP Code:
Other languages have different tricks for this. Ruby/Smalltalk/Perl can pass an anonymous block of code (PHP lambda functions are rubbish by comparison). Java can pass an anonymous inner class to avoid polluting the namespace. For functional languages, callbacks are the foundation. It's how you get the code to the data. You will see things like "list comprehensions" (basically generators and transformers) used in the same context. Python has some support for this, but I'm not a Python developer, so hopefully someone else will elaborate. yours, Marcus
__________________
Marcus Baker Testing: SimpleTest, Cgreen, Fakemail Other: Phemto dependency injector Books: PHP in Action, 97 things Last edited by lastcraft; Jan 18, 2006 at 09:16.. Reason: Fixed code glitch |
|
|
|
|
|
#9 |
|
Community Advisor
![]() ![]() Join Date: Jun 2004
Location: Copenhagen, Denmark
Posts: 6,048
|
And, may I add, javascript excells in this. Since functions are variables, they can be passed around. Gives you plenty of ammunition to shoot yourself, or tools to write some encredibly beautiful code, depending on your skills.
|
|
|
|
|
|
#10 |
|
SitePoint Wizard
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Aug 2003
Location: UK
Posts: 1,020
|
Yeah, can do nice things with javascript. Even create anonymous objects, with methods
Code:
var a = [3, 4, 5];
run = function(a, o) { for(i in a) { o.visit(a[i]); } };
var o = { total: 0, visit: function(v) { this.total += v; } };
run(a, o);
alert(o.total);
|
|
|
|
|
|
#11 | |
|
SitePoint Guru
![]() ![]() ![]() ![]() ![]() Join Date: Jan 2004
Location: Oslo, Norway
Posts: 894
|
Quote:
Let me try a canonical form for the client code: PHP Code:
__________________
Dagfinn Reiersøl PHP in Action / Blog / Twitter "Making the impossible possible, the possible easy, and the easy elegant" -- Moshe Feldenkrais |
|
|
|
|
|
|
#12 | |
|
SitePoint Zealot
![]() ![]() Join Date: Jul 2004
Location: The Netherlands
Posts: 170
|
Quote:
Off Topic: Regarding functional programming, currying et al, there are some nice examples here as well. JavaScript can be a lot of fun
|
|
|
|
|
|
|
#13 |
|
SitePoint Wizard
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Apr 2004
Location: germany
Posts: 4,324
|
Currying in php
PHP Code:
![]() |
|
|
|
|
|
#14 | ||
|
SitePoint Victim
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Apr 2003
Location: London
Posts: 2,385
|
Hi...
Quote:
http://www.rubycentral.com/book/lib_patterns.html OK, that doesn't explain much, because it just points you at "each". They had a better article somewhere, but I couldn't find it. I am on a bit of "replace iterator with visitor" mission at the moment at work, so this is on my brain right now. Quote:
But then, patterns are fuzzy things best deployed subconsciously I think. yours, Marcus
__________________
Marcus Baker Testing: SimpleTest, Cgreen, Fakemail Other: Phemto dependency injector Books: PHP in Action, 97 things |
||
|
|
|
|
|
#15 | |||
|
SitePoint Guru
![]() ![]() ![]() ![]() ![]() Join Date: Jan 2004
Location: Oslo, Norway
Posts: 894
|
Quote:
Visitor allows you to add new operations to a class without putting them in the class itself. Quote:
Quote:
__________________
Dagfinn Reiersøl PHP in Action / Blog / Twitter "Making the impossible possible, the possible easy, and the easy elegant" -- Moshe Feldenkrais |
|||
|
|
|
|
|
#16 | |
|
Non-Member
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jan 2003
Posts: 5,788
|
Quote:
|
|
|
|
|
|
|
#17 | |
|
SitePoint Victim
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Apr 2003
Location: London
Posts: 2,385
|
Hi...
Quote:
Ruby Mixins are the metaclass stuff. It's actually the ruby block that's replacing the visitor... Code:
class IterableFromWithin
def each()
names.sort.each { |name|
yield(name)
}
end
def names
return ['Marcus', 'Dagfinn']
end
end
# Pass callback as a block.
IterableFromWithin.new.each { |item| print 'Hello ' + item }
__________________
Marcus Baker Testing: SimpleTest, Cgreen, Fakemail Other: Phemto dependency injector Books: PHP in Action, 97 things |
|
|
|
|
|
|
#18 |
|
SitePoint Guru
![]() ![]() ![]() ![]() ![]() Join Date: Jan 2004
Location: Oslo, Norway
Posts: 894
|
IMHO it's not a Visitor unless it
The Visitor pattern is apparently not necessary in Ruby, so I wouldn't expect Ruby experts to explain it well.
__________________
Dagfinn Reiersøl PHP in Action / Blog / Twitter "Making the impossible possible, the possible easy, and the easy elegant" -- Moshe Feldenkrais |
|
|
|
|
|
#19 | ||
|
SitePoint Victim
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Apr 2003
Location: London
Posts: 2,385
|
Hi...
Quote:
PHP Code:
PHP Code:
Quote:
I do agree that I have stretched it as much as the pragmatic programmers have stretched it. I kind of hope the "Prags" win, though. I find the GOF explanation is truly horrible. yours, Marcus
__________________
Marcus Baker Testing: SimpleTest, Cgreen, Fakemail Other: Phemto dependency injector Books: PHP in Action, 97 things |
||
|
|
|
|
|
#20 | |
|
SitePoint Addict
![]() ![]() ![]() Join Date: Aug 2003
Location: Toronto
Posts: 303
|
Quote:
|
|
|
|
|
|
|
#21 |
|
Web developer
![]() ![]() ![]() Join Date: Sep 2003
Location: sweden
Posts: 321
|
If you want to look at PHP callbacks in the wild the you should take a look at the Drupal CMS code. It is built entirely on the callback functionallity for everything from access control, templating and the use of hooks and overriding functions. A few months ago I wrote a couple of shorties about the why's and do nots of using PHP callbacks.
http://www.hivemindz.com/drupal_reas...ork#comment-82 http://www.hivemindz.com/aggregation_vs_callback I was waiting for more info and examples to come to the PHP5 manual on aggregate functions before writing more but they are still not there.
__________________
FHQK ed UP - It's a really FHQK ed UP world we live in! Hiveminds Magazine Search Engine for Drupal Search Engine for Students |
|
|
|
|
|
#22 |
|
Web developer
![]() ![]() ![]() Join Date: Sep 2003
Location: sweden
Posts: 321
|
About 80% of Drupal is built around this code
PHP Code:
__________________
FHQK ed UP - It's a really FHQK ed UP world we live in! Hiveminds Magazine Search Engine for Drupal Search Engine for Students |
|
|
|
|
|
#23 |
|
SitePoint Zealot
![]() ![]() Join Date: Jul 2004
Location: Melbourne
Posts: 173
|
I'm suprised it took a mention of Drupal to bring up the call_user_func set of functions. I use callbacks in my template class to format column output for tabular data. An example would be something like date formatting. ddmmyy vs mmddyy vs ... you get the point. If I have a callback function created to handle the date formatting, I can tell my code to that the callback should be run without running it until its needed if that makes sense. It essentially means one function call in my code (make the code cleaner in this instance), but allows me to make smarter decisions at runtime based on user preferences without cluttering up my code. I know which function I want to run, but I dont necessarily know what parameters I want to pass through to it.
All said and done, its just another method of accomplishing the same thing. There are only a few problems I think that can only be solved with callbacks as opposed to just standard procedural/OO code. I think php its main strength is giving coders the ability to couple a php function with a c function in a php extension. As mentioned above with the xml functions, you can feed it the name of the php function you want to run every time the appropriate point/event in the extension code is triggered. This isn't possible (at least that I'm aware of) without callbacks. Marcus, your guess of C# delegates being like callbacks is close. Delegates are closer to function pointers. You have to give them an address for the function you want to call as opposed to calling them by name. For the sake of arguement though, in php, the difference is probably very minimal. In fact in the extension to php callback scenario I described, it more or less is behaving like a delegate, just without the php land code having to pass through the memory address. Zend Engine probably does that internally though, so I would guess it gets converted to a function pointer/delegate on throughput.
__________________
http://www.realityedge.com.au |
|
|
|
|
|
#24 |
|
SitePoint Guru
![]() ![]() ![]() ![]() ![]() Join Date: Nov 2002
Posts: 846
|
Wact does something like this:
PHP Code:
The Notifier objects (UnicastNotifier and MulticastNotifier) support three styles:
The Callback object is mostly a wrapper for call_user_func_array with an invoke method. PHP Code:
PHP Code:
PHP Code:
|
|
|
|
|
|
#25 | |
|
Community Advisor
![]() ![]() Join Date: Jun 2004
Location: Copenhagen, Denmark
Posts: 6,048
|
Quote:
|
|
|
|
|
![]() |
| Bookmarks |
«
Previous Thread
|
Next Thread
»
| Thread Tools | |
| Display Modes | |
|
|
|
All times are GMT -7. The time now is 06:02.















Linear Mode
