PHP interface optional parameter

Classes implementing a method defined as an abstract signature on a parent class or by an interface must follow certain rules, but they do not have to match exactly.

This is not well documented, for example it's not even mentioned in the PHP documentation of interfaces, but is touched upon by the documentation of abstract classes:

Furthermore the signatures of the methods must match, i.e. the type hints and the number of required arguments must be the same. For example, if the child class defines an optional argument, where the abstract method's signature does not, there is no conflict in the signature.

In other words, the method must be capable of being called as per the signature, but it doesn't rule out:

  1. Using different variable names in the implementation of the method
  2. Declaring additional optional arguments after the arguments declared in the method signature, if any

Taken from the question, this would work:

interface ServiceInterface{

    public static function create($var1, $var2);

}

class ServiceObject1 implements ServiceInterface{

    public static function create($url, $server){
       //....
    }
 }

class ServiceObject2 implements ServiceInterface{

    public static function create($methode, $url, $id = null){
       //....
    }
}

It's not the proper way to implement an interface.

First of all, an interface defines how a class should be used and an optional parameter could break this reason.

Besides that, even you have exactly two parameters, they should have its own meaning and this meaning should be shared.

There's a huge difference between the interface method signature:

public static function create($var1, $var2);

and the two implemented methods:

public static function create($url, $server)

and:

public static function create($methode, $url)

Also, AFAIK, implementing this way will rise a strict standard violation because you're changing the interface signature.

If you have to create a shared interface that has no meaning, there's no reason to the interface be shared or even created.


In PHP 56+, you can use the ellipsis operator:

interface ServiceInterface {
    public static function create(...$params);
}

class ServiceObject1 implements ServiceInterface
{
    public static function create(...$params)
    {
        $url = $params[0];
        $server = $params[1];
        print "url = $url\n";
        print "server = $server\n";
    }
}

class ServiceObject2 implements ServiceInterface
{
    public static function create(...$params)
    {
        $method = $params[0];
        $url = $params[1];
        $id = $params[1];
        print "method = $method\n";
        print "url = $url\n";
        print "id = $id\n";
    }
}
print "ServiceObject1::create\n";
ServiceObject1::create("url", "server");
print "\nServiceObject2::create\n";
ServiceObject2::create("method", "url", "id");

Output:

ServiceObject1::create
url = url
server = server

ServiceObject2::create
method = method
url = url
id = url

/rant

To users complaining about what the OP want's to do - While general advice is that this is bad idea to do, there exsist many cases in which the program really does not care what the parameters are in advance. An example of this would be if ther function was sumAll instead of create.

Tags:

Php

Oop

Interface