Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to define method with different parameters in a PHP interface?

I'm developing a service that is being injected a Logger object but I can have 2 different kind of loggers, I'm planning on having a syslog logger and a queue message system logger. Is this possible?

The idea is having an interface:

interface Loggable
{
    public function log() ;
}

and 2 classes that implement that interface:

class Syslogger implements Loggable
{
    public function log()
    {
        ...
    }
}

class QMSLogger implements Loggable
{
    public function log($queueName)
    {
        ...
    }
}

The only way I could come with is having an array as a parameter and use it on one class and not using on the other one... but that is a little bit smelly :P

like image 731
Khriz Avatar asked Dec 20 '12 10:12

Khriz


People also ask

Can we implement multiple interfaces in PHP?

implements ¶Classes may implement more than one interface if desired by separating each interface with a comma. A class can implement two interfaces which define a method with the same name, only if the method declaration in both interfaces is identical.

CAN interface have properties PHP?

Interfaces cannot have properties, while abstract classes can. All interface methods must be public, while abstract class methods is public or protected. All methods in an interface are abstract, so they cannot be implemented in code and the abstract keyword is not necessary.

What are parameters in php?

PHP Parameterized functions They are declared inside the brackets, after the function name. A parameter is a value you pass to a function or strategy. It can be a few value put away in a variable, or a literal value you pass on the fly. They are moreover known as arguments.

Does PHP support interface?

A PHP interface defines a contract which a class must fulfill. If a PHP class is a blueprint for objects, an interface is a blueprint for classes. Any class implementing a given interface can be expected to have the same behavior in terms of what can be called, how it can be called, and what will be returned.


2 Answers

You're asking if it's possible: yes it is, but…

If you implement an interface, you must respect its contract.

interface Loggable
{
    public function log();
}

This interface's contract is you can call log() without any parameter.

In order to respect that, you can make the parameter optional:

class QMSLogger implements Loggable
{
    public function log($queueName = null)
    {
        ...
    }
}

This is perfectly valid PHP and it respects the Liskov Substitution Principle. Of course, you must not use that optional parameter when coding against the interface, else you are obviously breaking the interface. Such parameter can be useful only when you are using the implementation (e.g. in some part of the code which is tightly coupled to the QMSLogger).

However this is probably not the solution to your problem as $queueName seems to be a configuration value and it might be better to pass it in the class' constructor (as explained in the other answer).

like image 81
Matthieu Napoli Avatar answered Oct 21 '22 19:10

Matthieu Napoli


I came across a similar case where I wanted to create an interface that simply ensure any classes that implemented it would have a method of the same name, but would allow for implementation with different parameters.

/**
 * Interface Loggable
 * @method log
 */
interface Loggable
{

}

Now the Loggable interface can be implemented with different parameters like so.

class Syslogger implements Loggable
{
    public function log($key, $value)
    {
        ...
    }
}
like image 44
Stephen Neal Avatar answered Oct 21 '22 19:10

Stephen Neal