Function Overloading and PHP

I’m proud of writing elegant code that can be easily read and intuitively understood. I use whitespace to increase my code’s readability, and I utilize simple, specialized programming language constructs to make my code more concise. For example, I’ll use PHP’s foreach construct, instead of a traditional for loop, to eliminate unnecessary indexers. This construct can also be found in Java, C#, Perl, as well as other programming languages. I also frequently use a PHP idiom, which I have never used in other languages, that allows for the convenient addition of elements into an array.

Because PHP features nonessential elements such as the array append operator, I am irked by PHP’s lack of a more useful feature: function overloading. The popular approach of appending a formal argument’s type to a function name is bothersome and inconvenient. The scheme begins to deteriorate source code aesthetics when the functions that require overloading accept more than one argument. Additionally, calling functionName($objectOfTypeA) and functionName($objectOfTypeB) is clearly more elegant than having to call functionNameTYPEA($objectOfTypeA) and functionNameTYPEB($objectOfTypeB). Function overloading would allow people to use a consistent interface, while allowing the implementation of a function to vary depending on the number and types of supplied arguments. Surely, there must be a way that type hints can be exploited to implement this much needed feature.

23 Responses to “Function Overloading and PHP”

  1. umer singhera Says:

    nice topic for beginers

  2. Joe Shcmoe Says:

    First, I know this is an old blog, but I have to make some comments on it.

    1.) Being a native C/C++/C#/Java (among others) programmer, I cannot agree more with the plight of PHP not having function overloading .. it can be VERY cumbersome and annoying having to write duplicate code to handle multiple subsets of data and objects .. thankfully though PHP at least has optional parameters that can make life a little easier (yes, there are other ways to emulate overloading, but the point of writing ‘pretty’ code is more for the next guy who takes over the project, or yourself 6 months later).

    2.) I don’t like bashing blogger’s or article writers, but I also don’t like the spreading misinformation about code. It is not more ‘elegant’ to use a foreach iterative loop vs. a standard ‘for’ loop. It REALLY depends on what you’re trying to accomplish. A ‘foreach’ loop uses an enumerable pointer type to loop through the array of objects. And depending on your object type, this COULD potentially be more costly than directly referencing the array variable itself (i.e. $Array[$i]->SomeMember) as an enumerable pointer type must be created (under the hood) and then passed back to the loop .. Plus, if you ARE using a ‘foreach’ iteration, you cannot directly assign a member to that pointer, nor can you remove it from the array in a ‘foreach’ loop without thrashing your memory. Example:

    foreach ($ArrOfObjs as $obj) {
    unset($obj);
    $obj = new ObjectType();
    }

    In this example, unset and the creation (new) will not throw errors (not in PHP anyways), but it won’t work either, the members of the array are not affected in anyway because enumerable pointer types ($obj in this foreach loop) are immutable/const (for the sake of discussion I wont’ get into the full nitty gritty of what a foreach loop really does)

    There are plenty of times when a foreach is fine (quick echo’ing out members for example), then there are plenty of times when a standard ‘for’ is fine (speed/memory for example or when you need to directly assign/remove items from an array for example).

    Also a ‘for’ loop can be much faster than a foreach (since no extra variables or enumerations have to be created) depending on certain situations

    3.) Again, I don’t like bashing blogger, but I have to point out that the OP does not understand what an ‘indexer’ is. An indexer allows for a class to be ‘index-able’ (if you will) similar to how you can index an array. Just google “C# indexers” and you’ll get a better understanding. Indexers (in this context) ARE a pretty C# specific context as well, there are notions and concepts of indexing similar to this context of an ‘indexer’ in C/C++ but they are mostly for when dealing with threads/mutex/etc.

    Sorry for the long post, but I hate when newbies come to places like this and take some blogger’s view/idea as hard fact in what is happening under the hood of a program/script .. If you know/are learning PHP and DON’T know at least some basic concepts of C++ (not C) I HIGHLY recommend reading some basics of C++. It will help to better grasp what your PHP scripts are doing under the hood.

    @varsha:
    since you have extend class A (parent) into class B (child), and are referencing class B, any methods you call that exist in both classes will only be called from your referencing member (i.e. class B only in your example). Depending on what you are trying to accomplish you can do multiple things. Class A can be an abstract class that has no functionality in it. Class A could be an interface that Class B uses. OR if Class A has functionality in it that you want to keep, but want to override one of its functions in its child class (Class B) and call class A’s function from within class B, you would do the ‘parent::Method()’ call.

    Example:

    class A {
    function score() {
    echo ‘You called class A::score()’;
    }
    }

    class B extends A {
    function score($param) {
    echo ‘You called class B::score with parameter of ‘ . $param . “\n”;
    parent::score();
    }
    }

    $obj = new B();
    $obj->score(10);

    output:
    You called class B::score with parameter of 10
    You called class A::score()

    Read up on class inheritance (in other langauges superclasses and sub classes are refered to as parent and child)

  3. varsha Says:

    i am extending a class A in class B.. which contain same method score() with different arguments..say, score() in class A and score($counter) in class B.Now By making object of class B only..i tried to access both methods.. say,
    $obj=new B();
    $obj->score();
    $obj->score($counter).
    Now, it is showing error as “Argument missing for first call to score()”
    It is not able to recognize the method from superclass A which is inherited in subclass B.

    Function overloading concept fail in php…
    help to sort out problem…plz..
    regards..
    varsha..(Student)

  4. FSGale Says:

    ooops… I guess php tags aren’t acceptable for this. The first example should look like:

    class myClass
    {
    public function myFunc();
    public function myFunc($myVar);
    }

    The second example only partially was displayed and should have been (I adjusted the conditionals for a more readable example):

    class myClass
    {
    public function myFunc()
    {
    $argc = func_num_args();
    $argv = func_get_args();

    if (1 === $argc)
    {
    if (is_string($argv[0]))
    {
    return $this->firstFunc($argv[0]);
    }
    elseif (is_integer($argv[0]))
    {
    return $this->secondFunc($argv[0]);
    }
    }
    return false;
    }
    private function firstFunc($myStr)
    {
    /* do something */
    }
    private function secondFunc($myInt)
    {
    /* do something */
    }
    }

  5. FSGale Says:

    @Ravinder Kumar

    Function overloading has been discussed above, but here is a clear example:

    See how two functions are defined with the same name? This is true function overloading by having two or more functions with the same name, but have different input parameters (and in some languages where you can actually specify the expected return value(s), this too can vary from method to method). This is not actually possible in PHP natively, and must be handled in different ways. One example of how this is possible is the following:

    firstFunc($argv[0]);
    }
    elseif (1 === $argc && is_integer($argv[0]))
    {
    return $this->secondFunc($argv[0]);
    }
    /* if you need more conditionals based on function input, add here */
    else
    {
    return false;
    }
    }
    private function firstFunc($myVar)
    {
    /* do something */
    }
    private function secondFunc($myVar)
    {
    /* do something */
    }
    }
    ?>

    Now there are other methods of handling this circumstance with PHP (examples have been provided above), but this should at least give you enough information to see how it can be done. If you prefer another method, then by all means use it if you feel comfortable with it. I honestly have not done any sort of performance testing to see which method may be better overall, so as far as I’m concerned they are most likely all equal (relatively) or at least close enough that it most likely doesn’t matter which one you do use. Obviously the conditionals in myFunc of the above example may need to be entirely changed to adjust for your own overloading conditions.

Leave a Reply