thephpleague / route

Fast PSR-7 based routing and dispatch component including PSR-15 middleware, built on top of FastRoute.
http://route.thephpleague.com
MIT License
651 stars 126 forks source link

how to pass response object to controller when dispatch #228

Closed shyandsy closed 5 years ago

shyandsy commented 5 years ago

I created the container object in index.php, and then add the response class to it

// 服务容器
$container = new League\Container\Container;
$container->add(ServerRequestInterface::class, Request::class);
$container->add(ResponseInterface::class, Response::class);

then, I build the route and dispatch the request

// create route
$strategy = (new League\Route\Strategy\ApplicationStrategy)->setContainer($container);
$router = (new League\Route\Router)->setStrategy($strategy);

// set route
$router->map('GET', '/', 'Controllers\HomeController::index');

// dispatch
$response = $router->dispatch($request);

finally, I wanna the action method receive both request and response object, instead of, create response object in every action method

namespace Controllers;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Zend\Diactoros\Response;

class HomeController extends Controller{
    public function __construct(ServerRequestInterface $request, Response $response){
        var_dump($response);
        $response = new Response();
        $response->getBody()->write('<h1>Hello, World!</h1>');
        return $response;
    }
}

unfortunately, the construct method get 0 parameters

Fatal error: Uncaught ArgumentCountError: Too few arguments to function Controllers\Controller::__construct(), 0 passed in Route.php on line 114 and exactly 2 expected in Controller.php on line 16

so are there any way to do that?

philipobenito commented 5 years ago

In the latest version we have moved to a single pass controller signature. This means that only the request and route args are passed to the controller, you are expected to create and return a response yourself.

Sent from my iPhone

On 2 Feb 2019, at 06:26, shyandsy notifications@github.com wrote:

I created the container object in index.php, and then add the response class to it

// 服务容器 $container = new League\Container\Container; $container->add(Zend\Diactoros\Response::class); then, I build the route and dispatch the request

// create route $strategy = (new League\Route\Strategy\ApplicationStrategy)->setContainer($container); $router = (new League\Route\Router)->setStrategy($strategy);

// set route $router->map('GET', '/', 'Controllers\HomeController::index');

// dispatch $response = $router->dispatch($request); finally, I wanna the action method receive both request and response object, instead of, create response object in every action method

namespace Controllers; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Zend\Diactoros\Response;

class HomeController extends Controller{ public function index(ServerRequestInterface $request, Response $response){ var_dump($response); $response = new Response(); $response->getBody()->write('

Hello, World!

'); return $response; } } unfortunately, the second parameter of this action index is an empty array

so are there any way to do that?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.

shyandsy commented 5 years ago

are there anyway to get container in controller?

On Sat, Feb 2, 2019 at 2:15 PM Phil Bennett notifications@github.com wrote:

In the latest version we have moved to a single pass controller signature. This means that only the request and route args are passed to the controller, you are expected to create and return a response yourself.

Sent from my iPhone

On 2 Feb 2019, at 06:26, shyandsy notifications@github.com wrote:

I created the container object in index.php, and then add the response class to it

// 服务容器 $container = new League\Container\Container; $container->add(Zend\Diactoros\Response::class); then, I build the route and dispatch the request

// create route $strategy = (new League\Route\Strategy\ApplicationStrategy)->setContainer($container); $router = (new League\Route\Router)->setStrategy($strategy);

// set route $router->map('GET', '/', 'Controllers\HomeController::index');

// dispatch $response = $router->dispatch($request); finally, I wanna the action method receive both request and response object, instead of, create response object in every action method

namespace Controllers; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Zend\Diactoros\Response;

class HomeController extends Controller{ public function index(ServerRequestInterface $request, Response $response){ var_dump($response); $response = new Response(); $response->getBody()->write('

Hello, World!

'); return $response; } } unfortunately, the second parameter of this action index is an empty array

so are there any way to do that?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/thephpleague/route/issues/228#issuecomment-459995889, or mute the thread https://github.com/notifications/unsubscribe-auth/AFBvoamqogThwOd7q3f0bWt-o-2derrgks5vJfH2gaJpZM4afcrX .

-- Yang Shi 201-15 bridgeland dr south R3Y 0E7

jokerham commented 5 years ago

I have created an abstract controller and used the container directly, then extended it to all my controllers.

class AbstractController
{
    protected $container;

    public function __construct()
    {
        $this->container = new Container();
    }
}