views:

97

answers:

9

Can you declare a function like this...

function ihatefooexamples(){
  return "boo-foo!";
};

And then redeclare it somewhat like this...

if ($_GET['foolevel'] == 10){
  function ihatefooexamples(){
    return "really boo-foo";
  };
};

Is it possible to overwrite a function that way?

Any way?

A: 

No this will be a problem. PHP Variable Functions

Chris
A: 

I'm afraid there's no way to do that.

Maerlyn
+5  A: 

Have a look at override_function to override the functions.

override_function — Overrides built-in functions

Example:

override_function('test', '$a,$b', 'echo "DOING TEST"; return $a * $b;');
Sarfraz
this is a good point but if the function is large, its not nice to pass in strings that long! :(, another point is that this can only be used for built in functions and not user defined!
RobertPitt
@RobertPitt: Agreed this is what we have at the moment and your solution looks good but that depends on php version being used.
Sarfraz
Why would you not want to be on a php version < 5.3.0? unless your building a script that would be retailed/released to the public then you have a valid point.
RobertPitt
@RobertPitt: I am using 5.3 and hope OP is using the same too :)
Sarfraz
+2  A: 

short answer is no, you can't overwrite a function once its in the PHP function scope.

your best of using anonymous functions like so

$ihatefooexamples = function()
{
  return "boo-foo!";
}

//...
unset($ihatefooexamples);
$ihatefooexamples = function()
{
   return "really boo-foo";
}

http://php.net/manual/en/functions.anonymous.php

RobertPitt
Do you really need the `unset`? I know it isn't bad to do, just curious (I haven't tried this specific case)...
ircmaxell
@ircmax You don't have to use `unset`
NullUserException
I haven't a clue on anonymous functions I just know they how to create them but iv'e never played with them, i understand that unset can be costly if overused but depending on the size of the function it might be better !
RobertPitt
A: 

Are you trying to override a simple function or would you be able to achieve what you want through the use of classes and extending them with override functions?

A bit more background in what you are trying to do would help.

Deane Venske
i dont think this si what he is looking for but a point non the less.
RobertPitt
+2  A: 

You could use the PECL extension

but that is bad practise in my opinion. You are using functions, but check out the Decorator design pattern. Can borrow the basic idea from it.

Gordon
+1  A: 

I would include all functions of one case in an include file, and the others in another include.

For instance simple.inc would contain function boofoo() { simple } and really.inc would contain function boofoo() { really }

It helps the readability / maintenance of your program, having all functions of the same kind in the same inc.

Then at the top of your main module

  if ($_GET['foolevel'] == 10) {
    include "really.inc";
  }
  else {
    include "simple.inc";
  }
ring0
+1  A: 

You cannot redeclare any functions in PHP. You can, however, override them. Check out overriding functions as well as renaming functions in order to save the function you're overriding if you want.

So, keep in mind that when you override a function, you lose it. You may want to consider keeping it, but in a different name. Just saying.

Also, if these are functions in classes that you're wanting to override, you would just need to create a subclass and redeclare the function in your class without having to do rename_function and override_function.

Example:

rename_function('mysql_connect', 'original_mysql_connect' );
override_function('mysql_connect', '$a,$b', 'echo "DOING MY FUNCTION INSTEAD"; return $a * $b;');
tomlikestorock
+3  A: 

This is where you should take advantage of OOP, specifically polymorphism.

interface Fooable
{
  public function ihatefooexamples();
}

class Foo implements Fooable
{
  public function ihatefooexamples()
  {
    return "boo-foo!";
  }
}

class FooBar implements Fooable
{
  public function ihatefooexamples()
  {
    return "really boo-foo";
  }
}

$foo = new Foo();

if ( 10 == $_GET['foolevel'] )
{
  $foo = new FooBar();
}

echo $foo->ihatefooexamples();
Peter Bailey
+1 for solving the actual problem, rather than simply trying to answer the exact question...
ircmaxell
The only change I would make would to put the `$foo = new Foo()` in an `else` block, in case either the constructor (a) is expensive, or (b) has side-effects.
Austin Hyde
@Austin - if `b` ever happens, then you've developed your class wrong. Instantiating objects via `new` should be idempotent. And I'd say `a` is extremely rare.
Peter Bailey
In the case where the output stays "foo-boo" and has just "really" added to it, I'd rather use a Decorator than a completely new Strategy
Gordon
@Gordon You're over-analyzing. I think it's pretty clear that this is just an example.
Peter Bailey
@Peter: I completely agree. It's just that not everybody makes their classes "right", or maybe there is actually a legitimate reason for side-effects (the only example that comes to mind is an instance counter). In my code, I overwrite variables like that all the time, but for public consumption, I would do it "not lazy" and use an `else` block.
Austin Hyde
@Peter well, maybe I am. But IMO the OP could have picked a more different example then. It's not too far fetched to suggest Decorator here. Not saying Strategy is wrong though.
Gordon
Who cares! Its FOO
Mark