Interface conflicts with PHP Pimple

196 Views Asked by At

I have a custom class that extends Pimple\Container. The idea was to wrap the, to my eyes, ugly methods for accessing defined services (see below):

offsetGet($key)       -> get($key)
offsetSet($key, $val) -> set($key, $val)
offsetExists($key)    -> has($key)

This idea worked fine for what i wanted to be able to do. i then went on to create an Application class that I chose INHERITANCE over AGGREGATION not for any particular reason than seeming to be logic.

The issue now is when I have a ServiceProvider that accepts an application instance instead of the Pimple\Container since I created my very own ServiceProviderInterface that defines this contract.

i realize now that assuming that Application was and still is a type of Container and have it use a different type of contract from the parent class wasn't a great idea. However, conceptually in my mind an application instance is some kind of a container because in it I have some key => value pair data stored.

I was thinking that Interface Segration principle would save my day but I am not sure.

  1. Could I have violated the Liskorv Substitution Principle here with my assumption with regards to the Application extends Pimple\Container relationship?

  2. Is there any way I can use my own Interface to register my service providers with stumbling on the error that whatever service I pass doesn't conform to the pimple\ServiceProvider contract?

In simply terms is it possible to extend Pimple's container and ignore the library's service provider and use your which defines the same contract but with different parameter?

1

There are 1 best solutions below

1
Henrique Barcelos On

First of all,

The idea was to wrap the, to my eyes, ugly methods for accessing defined services

The ugly methods are from the ArrayAcess interface, which allows you to access properties in an array-like form:

$container = new Pimple();
$container['session_storage'] = function ($c) {
    return new SessionStorage('SESSION_ID');
};

$container['session'] = function ($c) {
    return new Session($c['session_storage']);
};

i then went on to create an Application class that I chose INHERITANCE over AGGREGATION not for any particular reason than seeming to be logic

This is just wrong. You should always choose Aggregation over Inheritance when it is possible.

Inheritance is a static tightly-coupled relationship and it is limited to only one in PHP. You can't change inheritance during runtime.

Composition, in the other hand, is a dynamic and could be losely coupled if implemented respecting the SOLID principles. You can perfectly switch relationships during runtime when using composition.

The issue now is when I have a ServiceProvider that accepts an application instance instead of the Pimple\Container since I created my very own ServiceProviderInterface that defines this contract.

This makes no sense! Why would you Service Provider depend on your application? Shouldn't it be the other way around? The provider is a self-contained module. Your application has several dependencies.

About your questions,

  1. The best way of knowing if you violated the LSP is to ask yourself:
    Can I substituite a Container object for an Application object without any loss in functionality?

  2. Nop. Interfaces are contracts and contracts should be honored.