Guerrilla
Guerrilla

Reputation: 14886

Using interfaces in PHP

I am coming from C# and I am struggling to work out the PHP way of making my code extensible.

Lets say for instance I have a function that calculates my recommended daily allowance of food intake. It looks at vitamins, calories, minerals etc...

I want to have lots of different food objects that I use in my application and different functions that look at different aspects of food so I implement a IFoodNutrition interface and make my food classes that I want to be compatible with my function implement it. I then declare that my function takes it as an arg

function GetRda(IFoodNutrition $food){}

In C# I would specify all of the properties that I need to use in the interface so I know any class that implements this will be compatible with this function.

What is making my head hurt is that PHP only allows method signatures in interfaces.

My problems is obviously the paradigm shift. I am not sure what the equivalent pattern is in PHP. I have read the documentation and I can't see the like for like alternative unless you inherit from an abstract class but then you can only inherit from one class so that doesn't work the same way.

As PHP isn't typesafe I don't have to create the interface. Someone can just send any object to the method and if it has the properties needed in the right format it will work. This just doesn't seem right to me though as I am so used to laying out how things should be interacted with in interfaces.

I feel like there should at least be some extra step in the middle where the object is validated and some obvious structure that a developer can look at and then implement their own class intuitively and see errors before runtime.

Is there a specific pattern in PHP like this?

Upvotes: 11

Views: 646

Answers (3)

Edson Medina
Edson Medina

Reputation: 10269

You can't define properties in an interface in php.

It makes sense, because the function of the interface is to specify an API, not the implementation.

Upvotes: 0

Gabi Udrescu
Gabi Udrescu

Reputation: 96

My PHP knowledge is still limited, but I'll try a couple of answers about how I would tackle this problem.

1. quick and dirty (not recommended, imho, big no-no)

accept everything on the input, fail with an exception if the input is not valid.

    function getRda ($food) {

        if (!($food instanceof IInterface)) {
           throw new \Exception('function argument should be instance of IInterface');

        }

    //... do your magic
    }

2. suggest getters and setters through the interface

In the interface, suggest the presence of a property (e.g. getMinerals for $minerals)

3. use a trait

Although it's not going to help you much with establishing a contract between object interactions, it will help you keep you code DRY

e.g.

trait Food 
{
   protected $minerals;
   public function getMinerals ()
     {
        return $this->minerals;
     }
}

then, in every class you want multiple inheritence (the equivalent of, let's say, extending two abstract classes), use the trait above.

Upvotes: 0

Jason McCreary
Jason McCreary

Reputation: 72991

PHP only allows method signatures in interfaces.

This is true. However, nothing is stopping you from making traditional getters and setters for properties as part of the interface. Doing so abstracts underlying implementation details.

Someone can just send any object to the method and if it has the properties needed in the right format it will work.

This is not true. You have type-hinted the argument with IFoodNutrition $food. PHP will throw a fatal error if this function receives an object that does not implement the IFoodNutrition interface.

Upvotes: 6

Related Questions