简体   繁体   中英

How to use Symfony HttpFoundation with PHP-DI for MVC

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!

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();
    },
    // ...
];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM