Dismiss
Announcing Stack Overflow Documentation

We started with Q&A. Technical documentation is next, and we need your help.

Whether you're a beginner or an experienced developer, you can contribute.

Sign up and start helping → Learn more about Documentation →

If I have a function:

function this($a){
   return $a;
}

If I wanted to redefine the function, would it be as simple as rewriting it?

function this($a, $b){  //New this function
   return $a * $b;
}
share|improve this question
3  
as well as, or instead of? – Matt Ellen Apr 14 '10 at 20:58
    
Why do you want this? A function should be named to describe what it does. What's wrong with having 2 functions? – Bart S. Apr 14 '10 at 21:01
1  
I'm modifying a core script which has a defined function and rather than edit the function directly, I'd like to include a custom file that I could use to simply redefine the function to my needs. – Michael Apr 16 '10 at 7:27
3  
There are plenty of cases where one might want to modify an already existing function. For instance when writing test doubles (or mocks); or monkey patching libraries at runtime (without having to change the actual source code of the library). I actually find this limitation to be one of the most frustrating of PHP, as opposite to more dynamic programming languages such as Ruby or JavaScript, where this is not only possible, but is also done quite often. – Andrea Fiore May 30 '11 at 14:26
    
up vote 18 down vote accepted

Nope, that throws an error:

Fatal error: Cannot redeclare foo()

The runkit provides options, including runkit_function_rename() and runkit_function_redefine().

share|improve this answer

If you mean overloading in a Java sense, then the answer is no, this is not possible.

Quoting the PHP manual on functions:

PHP does not support function overloading, nor is it possible to undefine or redefine previously-declared functions.

You could use the runkit extension but usage of runkit in production scenarios is generally considered doubtful practice. If you want to exchange algorithms at runtime, have a look at the Strategy pattern or Anonymous functions instead.

If by redefine you mean add to an existing userland function, refactor, substitute or rewrite, then yes: it is as simple as you've shown. Just add the additional code to the function, but make sure you set a default for backwards compatibility.

Another option would be to use http://antecedent.github.io/patchwork

Patchwork is a PHP library that makes it possible to redefine user-defined functions and methods at runtime, loosely replicating the functionality runkit_function_redefine in pure PHP 5.3 code, which, among other things, enables you to replace static and private methods with test doubles.

share|improve this answer
    
Sorry, I misread your answer. I thought you said the opposite. The two other downvotes seem to indicate that I'm not the only person who made that mistake – Casebash Oct 7 '11 at 23:18
    
@Casebash thanks for taking your time to reread the answer. appreciated. – Gordon Oct 8 '11 at 8:00
    
@Gordon, These runkit extensions work deadly well. How is it "generally considered doubtful practice"? – Pacerier Mar 25 '15 at 15:03
    
@Pacerier because it is unobvious when function suddenly behave differently from their original definition. Especially when it comes to native functions which developers know well. You have to know that something changes this somewhere. – Gordon Mar 25 '15 at 15:26

You can't redefine or 'undefine' a function in PHP (without resorting to third-party modules). However, you can define a function conditionally.

So, if you know function A can be defined elsewhere, but not always, you can wrap it like this:

if (!function_exists('A')) {
    function A() {
        // default A implementation
    }
}

Then you only need to make sure the implementation you want is encountered first:

function A() {
    // another A implementation
}
share|improve this answer
    
With the further caveat that calls come after definitions. (Recent PHP doesn't care about call/define order for unconditionally defined functions.) – BobStein-VisiBone Jul 5 '13 at 22:50

I've got a library of functions that sometimes I just don't want invoked while I'm testing (typically database updates). If I have, for example, a few different db update functions that are all over the code. instead of commenting out the code, I just create a special class (e.g. class foo {}). Define a global variable (e.g., $DEBUG) and a dummy function (e.g., function dummy {}). Inside foo define all the (public static) functions you need to mimic as

$fn = isset($DEBUG) ? 'dummy' : 'real function'; return call_user_func_array($fn,func_get_args());

Plus you have the advantages of now doing other things, like logging the calls and parameters.

Then simply replace all your calls to real_function(...) with foo::real_function(...). Usually just a simple search/replace (or leave it there; depending on what's going on in the function and how often it's getting called the overhead may be irrelevant).

share|improve this answer

You can't have both functions declared at the same time, that will give an error.

share|improve this answer
    
This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. – dhh Oct 11 '15 at 15:55

You can't redeclare it. If your question is just about overloading that example, how about:

function this($a, $b=1)
{
    return $a * $b;
}
share|improve this answer

Setting an appropriate default to any new arguments that you add might help for backwards compatibility, i.e.:

function this($a, $b=1){  //New this function with a sane default.
    return $a * $b;
}

I also recommend, for clarity, generally avoiding using this for function/variable names.

share|improve this answer

I have good news and bad news.

The good news
It is possible (link(s) below).

The nadnews
There are 2 bad news:

By default, only userspace functions may be removed, renamed, or modified. In order to override internal functions, you must enable the runkit.internal_override setting in php.ini.

And the second bad news: You havbe to sacrifice code readability.

Example:

<?php
function this($a){
   return $a;
}

echo this(0);

$f_name = 'this';
$f_args = '$a';
$f_code = 'return $a*$b;';
runkit_function_redefine($f_name, f_args, f_code);

echo this(1,3);

Oh, and one more thing, using this as a name for a function may create confusion, due to the methods of a object of a class being able to use this.something to reffer to the variable something that is in the method and have the same name as the variable something from the object itself. Here is an example

<?php
class theclass{
  $a = 'a';
  function a($a){
    echo $a;
    $a = this.$a;
  }
}
theclass $object = new theclass();
$object -> a('b'); // will echo: ab
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.