# Slim Di Bridge and Interfaces

**URL:** <https://discourse.slimframework.com/t/slim-di-bridge-and-interfaces/1334>\
**Category:** Questions\
**Created:** [March 28, 2017, 2:58pm UTC](https://discourse.slimframework.com/t/slim-di-bridge-and-interfaces/1334 "2017-03-28T14:58:02Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![supervan1](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.slimframework.com/supervan1/32/362_2.png) [@supervan1](https://discourse.slimframework.com/u/supervan1)\
**Post date:** [March 28, 2017, 2:58pm UTC](https://discourse.slimframework.com/t/slim-di-bridge-and-interfaces/1334/1 "2017-03-28T14:58:02Z")

</div>

Hi, im using Slim3 Di Bridge and some Interfaces

Can someone please explain, i have tried to source the answers

1. I don’t understand why I need to create a flashInterface. I understand an interface is like a contract with rules that’s needed to be followed and implemented in a class.
2. The flash class and FlashInterface are all dummies, no rules, why do I need to create them, if I later need to add Swiftmailer do i also need to create an class and interface
3. The DI Bridge is autoloading Classes, in other words I don’t need to use “NEW” to create a class, just use it… ? In the MyApp, im still using “new” to create the link to the twig files.

Any better way of doing this? Not sure if my code is optimized

**MyApp.php** this is just a short version

```php
namespace App;

use DI\ContainerBuilder;
use Interop\Container\ContainerInterface;
use App\Interfaces\FlashInterface;
use App\Helpers\Flash;

class MyApp extends \DI\Bridge\Slim\App {

    protected function configureContainer(ContainerBuilder $builder) {
        $definitions = [
            'settings.displayErrorDetails' => true,
            \Slim\Views\Twig::class => function (ContainerInterface $container) {
                $view = new \Slim\Views\Twig( __DIR__. '/../twig/views', [
                    'cache' => false,
                ]);

                $view->addExtension(new \Slim\Views\TwigExtension(
                        $container->get('router'), $container->get('request')->getUri()
                ));

                $view->getEnvironment()->addGlobal('flash', $container->get('flash'));
                return $view;
            },
            FlashInterface::class => function () {
                return new Flash();
            },
            'flash' => \DI\get(FlashInterface::class),
        ];

        $builder->addDefinitions($definitions);
    }
}

```

**flash.php**

```php
namespace App\Helpers;

use Slim\Flash\Messages;
use App\Interfaces\FlashInterface;

class Flash extends Messages implements FlashInterface {
    // dummy
}

```

**FlashInterface.php**

```php
namespace App\Interfaces;

interface FlashInterface {
    // Dummy
}

```

---

<div class="post-metadata">

**Author:** ![tflight](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.slimframework.com/tflight/32/1205_2.png) [@tflight](https://discourse.slimframework.com/u/tflight)\
**Post date:** [March 28, 2017, 8:57pm UTC](https://discourse.slimframework.com/t/slim-di-bridge-and-interfaces/1334/2 "2017-03-28T20:57:17Z")

</div>

I use PHP-DI with Slim (using Slim-Bridge) but I’m far from an expert on this. Based on what I’d see, I’d say:

(1) I don’t think you need to.  
(2) Same, I don’t think you need to.  
(3) If you don’t put `new` there, I believe PHP will think `Slim\Views\Twig` is a function.

Are you trying to add the Slim\Flash extension? Or is this a different package?

---

<div class="post-metadata">

**Author:** ![supervan1](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.slimframework.com/supervan1/32/362_2.png) [@supervan1](https://discourse.slimframework.com/u/supervan1)\
**Post date:** [March 29, 2017, 3:37am UTC](https://discourse.slimframework.com/t/slim-di-bridge-and-interfaces/1334/3 "2017-03-29T03:37:17Z")

</div>

Hi Tim

Thanks for responding, I’m using the slim flash package extension, in  
theory I also think it should work, maybe my approach is wrong, do you  
perhaps have a skeleton code of a small project, that uses eloquent models,  
twig, slim flash,mono-log, swift-mailer that’s a email package, will do the  
comparison between mine and yours. Thanks

---

<div class="post-metadata">

**Author:** ![tflight](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.slimframework.com/tflight/32/1205_2.png) [@tflight](https://discourse.slimframework.com/u/tflight)\
**Post date:** [March 29, 2017, 11:30am UTC](https://discourse.slimframework.com/t/slim-di-bridge-and-interfaces/1334/4 "2017-03-29T11:30:48Z")

</div>

No, I don’t have a skeleton that uses those packages. But I can try to help get you going by helping with one or two. You can also use a crafted Google search to look for other packages that use certain combinations of tools. For example this search _should_ show you all packages that use both slim/flash as well as PHP-DI Slim Bridge.

`site:packagist.org/packages "slim/flash" "php-di/slim-bridge"`

Are you actually using [slim/flash](https://github.com/slimphp/Slim-Flash) or are you using [kanellov/slim-twig-flash](https://github.com/kanellov/slim-twig-flash)? If `slim/flash` then note that it doesn’t come with a Twig extension so you would likely need to write your own.

---

<div class="post-metadata">

**Author:** ![supervan1](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.slimframework.com/supervan1/32/362_2.png) [@supervan1](https://discourse.slimframework.com/u/supervan1)\
**Post date:** [March 29, 2017, 7:36pm UTC](https://discourse.slimframework.com/t/slim-di-bridge-and-interfaces/1334/5 "2017-03-29T19:36:36Z")

</div>

I got Slim Di Bridge working with flash and the dummy interfaces as displayed in the sample code posted earlier in this post. I don’t think I’m using the bridge to its full extend. Was looking for a fresh pair of eyes to brows the code.

```php
namespace App;

use App\Auth\CsrfGuard;
use App\Basket\Basket;
use App\Database\CapsuleDatabase;
use App\View;
use Carbon\Carbon;
use DI\ContainerBuilder;
use Interop\Container\ContainerInterface;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use Monolog\Processor\UidProcessor;
use Noodlehaus\ConfigInterface;
use Psr\Log\LoggerInterface;
use Slim\Exception\NotFoundException;
use Slim\Interfaces\RouterInterface;
use Slim\Views\TwigExtension;
//Handlers
use App\Handlers\ErrorCustom;
use App\Handlers\NotFoundCustom;
//Helpers
use App\Helpers\Flash;
use App\Helpers\Session;
use App\Helpers\SEmail;
//Interfaces
use App\Interfaces\Auth\CsrfGuardInterface;
use App\Interfaces\Auth\ValidationErrorsMiddleware;
use App\Interfaces\Auth\OldInputMiddleware;
use App\Interfaces\Auth\GuestMiddlewareInterface;
use App\Interfaces\Database\DatabaseInterface;
use App\Interfaces\Helpers\FlashInterface;
use App\Interfaces\Helpers\SessionInterface;
use App\Interfaces\ViewInterface;
//Models
use App\Models\Address;
use App\Models\Customer;
use App\Models\Order;
use App\Models\Payment;
use App\Models\Product;
//Support
use App\Support\Storage\Contracts\StorageInterface;
use App\Support\Storage\SessionStorage;
//Validation
use App\Validation\Contracts\ValidatorInterface;
use App\Validation\Validator;

class App extends \DI\Bridge\Slim\App {

    private $config;
    private $session;

    public function __construct(
    ConfigInterface $config
    ) {
        $this->config = $config;

        $this->session = new Session;

        if (!$this->session->isset1('csrfToken')) {
            $this->session->set('csrfToken', password_hash(time(), PASSWORD_BCRYPT));
        }

        $containerBuilder = new ContainerBuilder;
        $this->configureContainer($containerBuilder);
        $container = $containerBuilder->build();

        parent::__construct($container);
    }

    protected function configureContainer(ContainerBuilder $builder) {
        $definitions = [
            'settings.httpVersion' => $this->config
                    ->get('slimConfig.settings.httpVersion'),
            'settings.responseChunkSize' => $this->config
                    ->get('slimConfig.settings.responseChunkSize'),
            'settings.outputBuffering' => $this->config
                    ->get('slimConfig.settings.outputBuffering'),
            'settings.determineRouteBeforeAppMiddleware' => $this->config
                    ->get('slimConfig.settings.determineRouteBeforeAppMiddleware'),
            'settings.displayErrorDetails' => $this->config
                    ->get('slimConfig.settings.displayErrorDetails'),
            ViewInterface::class => function (ContainerInterface $container) {
                $view = new View($container->get('config')->get('twig.path'), [
                    'cache' => $container->get('config')->get('twig.cache'),
                    'debug' => $container->get('config')->get('twig.debug'),
                ]);

                $view->addExtension(new TwigExtension(
                        $container->get('router'), $container->get('request')->getUri()
                ));

                $view->addExtension(new \Twig_Extension_Debug());
                $view->addExtension(new \Twig_Extensions_Extension_Intl());

                $thisHost = $container->get('request')->getUri()->getScheme() . '://' .
                        $container->get('request')->getUri()->getHost();
                $thisBasePath = $container->get('request')->getUri()->getBasePath();
                $thisPath = $container->get('request')->getUri()->getPath();
                $thisUri = (string) $container->get('request')->getUri();

                $view->getEnvironment()->addGlobal(
                        'globals', [
                    'host' => $thisHost,
                    'basePath' => $thisBasePath,
                    'path' => $thisPath,
                    'thisUri' => $thisUri,
                    'cdn' => $container->get('config')
                            ->get('app.cdn'),
                    'css' => $container->get('config')
                            ->get('app.css'),
                    'js' => $container->get('config')
                            ->get('app.js'),
                    'images' => $container->get('config')
                            ->get('app.images'),
                    'csrfToken' => $this->session->get('csrfToken'),
                        ]
                );

                $view->getEnvironment()->addGlobal('flash', $container->get('flash'));
                $view->getEnvironment()->addGlobal('basket', $container->get(Basket::class));
                return $view;
            },
            'view' => \DI\get(ViewInterface::class),
            'errorHandler' => function (
            ViewInterface $view,
            ContainerInterface $container,
            LoggerInterface $logger
            ) {
                return new ErrorCustom(
                        $container->get('config'), $view, $logger
                );
            },
            'notFoundHandler' => function (
            ViewInterface $view,
            ContainerInterface $container,
            LoggerInterface $logger
            ) {
                return new NotFoundCustom(
                        $container->get('config'), $view, $logger
                );
            },
            LoggerInterface::class => function (ContainerInterface $container) {
                $logger = new Logger(
                        $container->get('config')->get('logger.name')
                );
                $logger->pushProcessor(new UidProcessor());

                $streamHandler = new StreamHandler(
                        $container->get('config')->get('logger.path'), Logger::DEBUG
                );

                $logger->pushHandler($streamHandler);

                return $logger;
            },
            'logger' => \DI\get(LoggerInterface::class),
            RouterInterface::class => function (ContainerInterface $container) {
                return $container->get('router');
            },
            // FlashInterface::class => \DI\object(Flash::class),
            FlashInterface::class => function () {
                return new Flash();
            },
            'flash' => \DI\get(FlashInterface::class),
            DatabaseInterface::class => function () {
                return new CapsuleDatabase();
            },
            'db' => \DI\get(DatabaseInterface::class),
            ConfigInterface::class => function () {
                return $this->config;
            },
            'config' => \DI\get(ConfigInterface::class),
            SessionInterface::class => function () {
                return $this->session;
            },
            'session' => \DI\get(SessionInterface::class),
            CsrfGuardInterface::class => function () {
                $null = null;
                return new \App\Auth\CsrfGuard('csrf', $null, function ($request, $response, $next) {
                            $route = $request->getUri()->getPath();
                            $parsedBody = $request->getParsedBody();
                            if (
                                    isset($parsedBody['csrfToken']) && $parsedBody['csrfToken'] === $this->session->get('csrfToken') && in_array($route, [
                                        'ajax/receive', // a route that receives ajax
                                            ]
                                    )
                            ) {
                                return $next($request, $response);
                            }
                            throw new \Exception('CSRF Problems on route: ' . $route);
                        }
                );
            },
            'csrf' => \DI\get(CsrfGuardInterface::class),
            ValidatorInterface::class => function (ContainerInterface $container) {
                return new Validator;
            },
            StorageInterface::class => function (ContainerInterface $container) {
                return new SessionStorage('cart');
            },
            OldInputMiddlewareInterface::class => function (ContainerInterface $container) {
                return new OldInputMiddleware();
            },
            ValidationErrorsMiddlewareInterface::class => function (ContainerInterface $container) {
                return new ValidationErrorsMiddleware();
            },
            GuestMiddlewareInterface::class => function (ContainerInterface $container) {
                return new GuestMiddleware();
            },
            Product::class => function (ContainerInterface $container) {
                return new Product;
            },
            Order::class => function (ContainerInterface $container) {
                return new Order;
            },
            Customer::class => function (ContainerInterface $container) {
                return new Customer;
            },
            Address::class => function (ContainerInterface $container) {
                return new Address;
            },
            Payment::class => function (ContainerInterface $container) {
                return new Payment;
            },
            SEmail::class => function (ContainerInterface $container) {
                return new SEmail();
            },
            Basket::class => function (ContainerInterface $container) {
                return new Basket(
                        $container->get(SessionStorage::class), $container->get(Product::class)
                );
            },
        ];

        $builder->addDefinitions($definitions);
    }

}

```

---

<div class="post-metadata">

**Author:** ![llvdl](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.slimframework.com/llvdl/32/78_2.png) [@llvdl](https://discourse.slimframework.com/u/llvdl)\
**Post date:** [March 30, 2017, 4:41pm UTC](https://discourse.slimframework.com/t/slim-di-bridge-and-interfaces/1334/6 "2017-03-30T16:41:29Z")

</div>

PHP-DI uses [autowiring](http://php-di.org/doc/autowiring.html), so you don’t need to (but you can) define the dependency in cases such as:

```php
        Product::class => function (ContainerInterface $container) {
            return new Product;
        },

```

and should even be automatically be able to create a `Basket` instance in your case.

---

<div class="post-metadata">

**Author:** ![llvdl](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.slimframework.com/llvdl/32/78_2.png) [@llvdl](https://discourse.slimframework.com/u/llvdl)\
**Post date:** [March 30, 2017, 6:45pm UTC](https://discourse.slimframework.com/t/slim-di-bridge-and-interfaces/1334/7 "2017-03-30T18:45:37Z")

</div>

You will need to add a definition for Slim\Flash\Messages, because the constructor has an optional argument that PHP-PI can’t automatically fill:

```php
class Messages {
    // PHP-DI autowiring doesn't know how to deal with $storage
    public function __construct(&$storage = null) 

```

I have the following:

```php
    Messages::class => function (ContainerInterface $container) {
        return new Messages();
    },

```

And then in the controller using [service injection](http://php-di.org/doc/frameworks/slim.html#service-injection):

```php
    public function __invoke(Request $request, Response $response, Messages $messages)
    {
        // ...
        $messages->addMessage('success', 'Something succeeded');
        // ...
    }

```

You don’t need to use an interface (such as FlashInterface), but it will make it easier later on to swap the implementation.

---

<div class="post-metadata">

**Author:** ![supervan1](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.slimframework.com/supervan1/32/362_2.png) [@supervan1](https://discourse.slimframework.com/u/supervan1)\
**Post date:** [March 31, 2017, 10:31am UTC](https://discourse.slimframework.com/t/slim-di-bridge-and-interfaces/1334/8 "2017-03-31T10:31:34Z")

</div>

Hi  
Thanks for responding.

The one thing that was confusing was the use of the dummy interface,  
Is this a typo error… the “&” in the public function \_\_construct(&$storage = null)

regards

---

<div class="post-metadata">

**Author:** ![tflight](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.slimframework.com/tflight/32/1205_2.png) [@tflight](https://discourse.slimframework.com/u/tflight)\
**Post date:** [March 31, 2017, 11:18am UTC](https://discourse.slimframework.com/t/slim-di-bridge-and-interfaces/1334/9 "2017-03-31T11:18:18Z")

</div>

No, that is a [PHP `reference`](http://php.net/manual/en/language.references.whatare.php). (But don’t ask me to explain them. ;))

---

<div class="post-metadata">

**Author:** ![supervan1](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.slimframework.com/supervan1/32/362_2.png) [@supervan1](https://discourse.slimframework.com/u/supervan1)\
**Post date:** [March 31, 2017, 12:21pm UTC](https://discourse.slimframework.com/t/slim-di-bridge-and-interfaces/1334/10 "2017-03-31T12:21:22Z")

</div>

lol, i understand, this is very cryptic
