Is it possible to overwrite a function in PHP

PhpFunctionRedeclaration

Php Problem Overview


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?

Php Solutions


Solution 1 - Php

Edit

> To address comments that this answer doesn't directly address the > original question. If you got here from a Google Search, start here

There is a function available called override_function that actually fits the bill. However, given that this function is part of The Advanced PHP Debugger extension, it's hard to make an argument that override_function() is intended for production use. Therefore, I would say "No", it is not possible to overwrite a function with the intent that the original questioner had in mind.

Original Answer

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();

Solution 2 - Php

Monkey patch in namespace php >= 5.3

A less evasive method than modifying the interpreter is the monkey patch.

Monkey patching is the art of replacing the actual implementation with a similar "patch" of your own.

Ninja skills

Before you can monkey patch like a PHP Ninja we first have to understand PHPs namespaces.

Since PHP 5.3 we got introduced to namespaces which you might at first glance denote to be equivalent to something like java packages perhaps, but it's not quite the same. Namespaces, in PHP, is a way to encapsulate scope by creating a hierarchy of focus, especially for functions and constants. As this topic, fallback to global functions, aims to explain.

If you don't provide a namespace when calling a function, PHP first looks in the current namespace then moves down the hierarchy until it finds the first function declared within that prefixed namespace and executes that. For our example if you are calling print_r(); from namespace My\Awesome\Namespace; What PHP does is to first look for a function called My\Awesome\Namespace\print_r(); then My\Awesome\print_r(); then My\print_r(); until it finds the PHP built in function in the global namespace \print_r();.

You will not be able to define a function print_r($object) {} in the global namespace because this will cause a name collision since a function with that name already exists.

Expect a fatal error to the likes of:

Fatal error: Cannot redeclare print_r()

But nothing stops you, however, from doing just that within the scope of a namespace.

Patching the monkey

Say you have a script using several print_r(); calls.

Example:
<?php
     print_r($some_object);
     // do some stuff
     print_r($another_object);
     // do some other stuff
     print_r($data_object);
     // do more stuff
     print_r($debug_object);

But you later change your mind and you want the output wrapped in <pre></pre> tags instead. Ever happened to you?

Before you go and change every call to print_r(); consider monkey patching instead.

Example:
<?php
    namespace MyNamespace {
        function print_r($object) 
        {
            echo "<pre>", \print_r($object, true), "</pre>"; 
        }

        print_r($some_object);
        // do some stuff
        print_r($another_object);
        // do some other stuff
        print_r($data_object);
        // do more stuff
        print_r($debug_object);
    }

Your script will now be using MyNamespace\print_r(); instead of the global \print_r();

Works great for mocking unit tests.

nJoy!

Solution 3 - Php

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;');

Solution 4 - Php

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

Solution 5 - Php

You cannot redeclare any functions in PHP. You can, however, override them. Check out [overriding functions][1] as well as [renaming functions][2] 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;');

[1]: http://php.net/manual/en/function.override-function.php "Function Overrides" [2]: http://www.php.net/manual/en/function.rename-function.php "Function Renaming"

Solution 6 - Php

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";
  }

Solution 7 - Php

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.

Solution 8 - Php

No this will be a problem. PHP Variable Functions

Solution 9 - Php

Depending on situation where you need this, maybe you can use anonymous functions like this:

$greet = function($name)
{
    echo('Hello ' . $name);
};

$greet('World');

...then you can set new function to the given variable any time

Solution 10 - Php

A solution for the related case where you have an include file A that you can edit and want to override some of its functions in an include file B (or the main file):

Main File:

<?php
$Override=true; // An argument used in A.php
include ("A.php");
include ("B.php");
F1();
?>

Include File A:

<?php
if (!@$Override) {
   function F1 () {echo "This is F1() in A";}
}
?>

Include File B:

<?php
   function F1 () {echo "This is F1() in B";}
?>

Browsing to the main file displays "This is F1() in B".

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMark LalorView Question on Stackoverflow
Solution 1 - PhpPeter BaileyView Answer on Stackoverflow
Solution 2 - Phpnickl-View Answer on Stackoverflow
Solution 3 - PhpSarfrazView Answer on Stackoverflow
Solution 4 - PhpRobertPittView Answer on Stackoverflow
Solution 5 - PhptomlikestorockView Answer on Stackoverflow
Solution 6 - PhpDéjà vuView Answer on Stackoverflow
Solution 7 - PhpGordonView Answer on Stackoverflow
Solution 8 - PhpChrisView Answer on Stackoverflow
Solution 9 - PhpesudView Answer on Stackoverflow
Solution 10 - PhpDavid SpectorView Answer on Stackoverflow