Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP interface optional parameter

Tags:

oop

php

interface

I'm trying to make an generic interface for my service classes. I'm having trouble with a two class making use of the interface. They share a methode called create. The create methode excepts three parameters. I want it to make it so that the third parameter is optional so that both classes can work with it.

interface ServiceInterface{

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

}

class ServiceObject1 implements ServiceInterface{

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

class ServiceObject2 implements ServiceInterface{

    public static function create($methode, $url, $id){
       //....
    }
}
like image 219
melkawakibi Avatar asked May 18 '17 11:05

melkawakibi


2 Answers

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){
       //....
    }
}
like image 77
Kelvin Jones Avatar answered Oct 30 '22 03:10

Kelvin Jones


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.

like image 32
Jdahern Avatar answered Oct 30 '22 03:10

Jdahern