Custom BaseController in Silex

I created a simple application in Silex 1.3.4, and I want to have a base controller that will have a __construct method that accepts $ app and $ request. All inheriting controllers must have appropriate constructors and call the parent controller build method.

//Use statements here....

class AppController
{
  public function __construct(Application $app, Request $request){
    $this->app = $app;
    $this->request = $request;
   }
 }

The following controllers will be written as follows:

//Use statements here....

class ItemsController extends AppController
{
  public function __construct(Application $app, Request $request){
    parent::__construct($app, $request);
   }

  public function listAction()
  {
    //code here without having to pass the application and request objects
   }
 }

The approach that I have defined for routing is given below:

   $app->post(
     '/items/list', 'MySilexTestDrive\Controller\ItemsController::listAction'
   )->bind('list');

I thought to use the dispatcher and redefine some processes there and create my own instances of the controller in my own way, but I don’t know how and if this is a great idea at all.

Anyone who has done something like this? Please, help.

+4
source share
3 answers

ServiceControllerServiceProvider, . Request . , , , . RequestStack, $requestStack->getCurrentRequest(), .

$app = new Silex\Application();

abstract class AppController
{
    protected $app;
    protected $requestStack;

    public function __construct(Silex\Application $app, Symfony\Component\HttpFoundation\RequestStack $requestStack)
    {
        $this->app = $app;
        $this->requestStack = $requestStack;
    }

    public function getRequest()
    {
        return $this->requestStack->getCurrentRequest();
    }
}

class ItemsController extends AppController
{
    public function listAction()
    {
        $request = $this->getRequest();
        // ...
    }
}

$app->register(new Silex\Provider\ServiceControllerServiceProvider());

$app['items.controller'] = $app->share(function() use ($app) {
    return new ItemsController($app, $app['request_stack']);
});

$app->get('/items/list', "items.controller:listAction");

​​? . , .

public function listAction(Application $app, Request $request)
{
    // ...
}

.

+4

:

class BaseController
{
    protected $app;
    protected $request;

    public function __call($name, $arguments)
    {
        $this->app = $arguments[0];
        $this->request = $arguments[1];
        return call_user_func_array(array($this,$name), [$arguments[0], $arguments[1]]);
    }

    protected function getSystemStatus(Application $app, Request $request)
    {
        [...]
    }
[...]
}
0

@Rabbis @Federico , BeforeControllerExecuteListener, . FilterControllerEvent, , Silex, .

public function onKernelController(FilterControllerEvent $event)
{
    $collection = $event->getController();
    $controller = $collection[0];

    if($controller instanceof BaseControllerAwareInterface){
        $controller->initialize($this->app, $event->getRequest());
      }
 }

, :

$app['dispatcher']->addSubscriber(new BeforeControllerExecuteListener($app));

, . , :

public function listAction($customer)
 {

     $connection = $this->getApplication()['dbs']['db_orders'];
     $orders= $connection->fetchAll($sqlQuery);

     $results = array();
     foreach($orders as  $order){
         $results[$order['id']] = $order['number'] . ' (' . $order['customer'] . ')';
      }


     return new JsonResponse($results);
  }

If the current controller that is being called is distinguished by the BaseControllerAwareInterface interface, as I defined it, then I must enter this controller with instances of the application and the request. I leave the controllers to decide how they control the response of each action, as with my example above. I might need the JsonResponse Response object itself, even any other type of response, so it depends entirely on the controller to take care of this.

Then the routing remains the same as:

$app->match('/orders/list/{cusstomer}', 'Luyanda\Controller\OrdersController::listAction')
->bind('list-orders');
0
source

Source: https://habr.com/ru/post/1609647/


All Articles