Page 1 of 2
[SOLVED]Passing functions as an argument.
Posted: Mon Dec 03, 2007 4:16 pm
by JellyFish
How can I pass a function or a block of code as function's argument?
In javascript I know i can like so:
Code: Select all
myFunction(function () {
//blcok of code
});
but how do I do this in php?
Thanks for reading, I hope it's more simple then I might think.
Posted: Mon Dec 03, 2007 5:27 pm
by volka
You can pass the function's name.
Code: Select all
<?php
function bar($x) {
echo $x*2;
}
function foo($fn) {
$fn(1234);
}
foo('bar');
Posted: Mon Dec 03, 2007 5:41 pm
by Christopher
Or pass either a string or array in the form for call_user_func(). That is the PHP standard for passing functions/object methods around.
Posted: Mon Dec 03, 2007 5:47 pm
by JellyFish
volka wrote:You can pass the function's name.
Code: Select all
<?php
function bar($x) {
echo $x*2;
}
function foo($fn) {
$fn(1234);
}
foo('bar');
Well, I'm really looking for a way to pass a handle that will be executed in the function. Err. For example, myFunction has one parameter, handle, and you pass in a block of code to be executed in myFunction. The only way to pass in blocks of code in javascript is through using a function. But sense you can really create functions as fluently in php is there another way to pass multiple statements to be executed?
Why I need this is because I'm creating an each() method for a class of mine. It will allow me to execute a block of code for each row of something or other. But basically it's an each() method.
Posted: Mon Dec 03, 2007 5:57 pm
by Christopher
Maybe if you showed and example of what you are trying to achieve.
Posted: Mon Dec 03, 2007 6:28 pm
by volka
You mean something like closures in python or ruby or maybe anonymous classes in java?
Posted: Mon Dec 03, 2007 9:35 pm
by JellyFish
Here's an example:
Code: Select all
database->each(array("query" => "SELECT...","callback" => /*passed in code*/));
This method to
database would call
callback for every row that's returned by
query. Now
callback needs to be a block of code to be executed for every row.
I hope it's clear of what I'm doing, I can't think of any other way to explain it.

Posted: Mon Dec 03, 2007 9:40 pm
by volka
'callback'=>'nameOfFunction'
Even if you use create_function() the return value will be the name of the newly created function as string.
Code: Select all
$fn = create_function('$x', 'return $x;');
var_dump($fn);
string(9) "
lambda_1"
Posted: Mon Dec 03, 2007 10:10 pm
by JellyFish
volka wrote:'callback'=>'nameOfFunction'
Even if you use create_function() the return value will be the name of the newly created function as string.
Code: Select all
$fn = create_function('$x', 'return $x;');
var_dump($fn);
string(9) "
lambda_1"
Hmm. I don't understand? You mean just define a function then pass it like you said before? The only problem with this is that I have this function that I defined left over. If I could create the function within the same statement like:
Code: Select all
database->each(array("callback" => function foo(){
//functions code
}));
Or if I could somehow delete a function:
Code: Select all
function foo() {
//functions code
}
database->each(array("callback" => 'foo'));
unset('foo');
I don't know if unset would be the correct function for removing a function.
Posted: Mon Dec 03, 2007 10:19 pm
by Christopher
Ok ... now I am really confused. You have a function "left over" that you want to "delete"? Honestly it sounds like you are trying to do something that there is probably a fairly normal solution for, but you are headed in some odd direction. I can't imagine that you really want to do what you think you want do to. Although you could simulate wacky things with calls like create_function() and eval(). It actually sounds like you want to implement something like the Command pattern...
What are you actually trying to do?
Posted: Mon Dec 03, 2007 10:33 pm
by JellyFish
I'm trying to pass a function as an argument for a method to a class of mine. Kind of like how I could do this in javascript:
Code: Select all
myobject.mymethod(function () {
//code
});
I would like to do it in php:
Code: Select all
myobject->mymethod(function () {
//code
});
But does it work in php like it does javascript? That was my question. And if the answer is no, then my other question is: How can i pass a function as an argument in php?
Well, volka said that I could do something like this:
Code: Select all
function foo()
{
//code
}
myobject->mymethod('foo');
but now I'm left with this foo function that I don't want, because it takes up namespace. And I don't think I can redefine a function if I ever wanted to call mymethod multiple times:
Code: Select all
function foo()
{
//code
}
myobject->mymethod('foo');
function foo()
{
//deferent code
}
myobject->mymethod('foo');
SO I would have to use a different name for my function other then foo. But then I would have to keep track of the functions that I created just to pass into a method.
Whew...
If you are still confused that answer this simple question: Will the follow code err?
Code: Select all
myobject->mymethod(function () {
//code
});
???
Posted: Tue Dec 04, 2007 12:07 am
by Christopher
The things in Javascript you describe are called Closures. Perhaps you could look around to see if anyone has hack to together a system that implements something like Closures. But I think a simpler solution would be to use the Command pattern.
http://www.phppatterns.com/docs/design/ ... nd_pattern
http://en.wikipedia.org/wiki/Command_pattern
The idea is, just like you showed, you pass a thing that has the same interface but contains different code. In your case it would be something like:
Code: Select all
class MyClass {
function mymethod($command) {
$command->foo()
}
}
$myobject = new MyClass();
class Bar1 {
function foo() {
//code
}
}
$myobject->mymethod(new Bar1($some, $params));
class Bar2 {
function foo() {
//deferent code
}
}
$myobject->mymethod(new Bar2($other, $params));
Posted: Tue Dec 04, 2007 4:20 am
by volka
In any way the function/method will exist for the remainder of the php instance.
Posted: Tue Dec 04, 2007 4:49 am
by vigge89
I'm guessing this is what you want?
Code: Select all
class object {
public function method($funcName) {
echo $funcName(1, 3); // should output 4
}
}
$function = create_function('$a, $b', "return (int)\$a+(int)\$b;");
$object = new object();
$object->method($function);
Posted: Tue Dec 04, 2007 8:52 pm
by JellyFish
vigge89 wrote:I'm guessing this is what you want?
Code: Select all
class object {
public function method($funcName) {
echo $funcName(1, 3); // should output 4
}
}
$function = create_function('$a, $b', "return (int)\$a+(int)\$b;");
$object = new object();
$object->method($function);
In a way yes. But the create_function doesn't appear to be very..."good". Not like javascript which uses, I guess you say, closure or lambda style programming.
I think I got my answer though.
I'll look more into it.
Thank you everyone, very much appreciated!
