0

I'm struggling to create a working MVC structure for a project.

What I'm using:

Here is my code.

container.php

$containerBuilder = new \DI\ContainerBuilder();
$containerBuilder->useAutowiring(true);
$containerBuilder->useAnnotations(true);
$containerBuilder->addDefinitions(__DIR__ . '/container-config.php');
$container = $containerBuilder->build();

container-config.php

use Twig\Environment;
use Twig\Loader\FilesystemLoader;
use Psr\Container\ContainerInterface;

return [

    'request' => function() {
        return Symfony\Component\HttpFoundation\Request::createFromGlobals();
    },

    'session' => function() {
        return new Symfony\Component\HttpFoundation \Session\Session();
    }

    Environment::class => function () {

        $loader = new FilesystemLoader(__DIR__ . '/../templates');
        $twig = new Environment($loader, [
            'cache' => __DIR__ . '/../var/cache/templates',
        ]);

        return $twig;
    },
];

router.php

use Pecee\SimpleRouter\SimpleRouter as R;
use Pecee\Http\Middleware\BaseCsrfVerifier;
use App\App;

R::csrfVerifier(new BaseCsrfVerifier());
R::setDefaultNamespace('\App\Controller');
R::enableDependencyInjection($container);

R::get('/', 'ProductController@index', ['as' => 'products']);

R::start();

Here is my base controller

namespace App;

use Symfony\Component\HttpFoundation\Request;
use Twig\Environment;

class BaseController
{

    protected $request;

    protected $twig;

    public function __construct(Request $request, Environment $twig)
    {

        $this->request = $request;

        $this->twig = $twig;

    }

}

Finally, my product controller

namespace App\Controller;

use App\BaseController;

class ProductController extends BaseController
{

    public function index()
    {

        dump($this->request); // returns the request object
        dump($this->request->query->all()); // return empty array

    }

}

The first problem is that the request object I set on the container, does not wok inside my controller.

Example url example.com?foo=bar

dump($this->request)

This line returns a Symfony\Component\HttpFoundation\Request as it should, but it seems to be a new one, because I can't get the query params with $this->request->query->all(), it returns empty.

If I create Symfony\Component\HttpFoundation\Request::createFromGlobals(); as a global variable, it works as expected, and dumping $this->request->query->all() returns the expected array.

So my question is, how do I best couple all these components together to be able to have a working structure?

Thank you!

C. Ovidiu
  • 1,104
  • 2
  • 18
  • 38
  • You can try changing 'request' => function() { to Request::class => function() { as is done for the Twig service. I am not familiar with PHP-DI but it seems reasonable that it needs the class name as a service id in order for autowire to work. – Cerad Jul 14 '20 at 12:11

1 Answers1

0

Nothing in PHP-DI suggests that dependency injection happens according to parameter names but instead the class is relevant. PHP-DI magically injects any class, if it is not (yet) defined. (The AnnotationBasedAutowiring will create a class from nothing if no definition is provided)

However, actually using annotations to trigger injections looks very different, and IMHO isn't apparently what you want, or you would have done so.

Since your definitions only contain an entry for request but not for Symfony\Component\HttpFoundation\Request, the container will happily create one for you.

To fix this, you have to set a different key, one that matches:

use Symfony\Component\HttpFoundation\Request; // <-- added

return [
    Request::class => function() {
        return Request::createFromGlobals();
    },
    // ...
];
Jakumi
  • 8,043
  • 2
  • 15
  • 32
  • Pretty sure you are misunderstanding the docs with respect to callables. I have not tried it myself but "Just like any other definition, factories are called once and the same result is returned every time the factory needs to be resolved." implies that the generated $request object will be shared wherever it is injected. Does not make much sense otherwise. – Cerad Jul 14 '20 at 14:38
  • @Cerad you are absolutely right. have adapted my answer. also, only now I've actually understood your original comment under the question ;o/ – Jakumi Jul 14 '20 at 14:41