PHP Slim框架创建控制器

PHP Slim框架创建控制器,php,controller,slim,slim-3,Php,Controller,Slim,Slim 3,我正在使用Slim框架创建一个API。目前,我使用单个文件创建路由并向其传递闭包: $app->get('/', function($req, $resp){ //Code... }) 但我意识到我的档案增长很快。我想做的是使用控制器,所以我将有一个控制器类,只需将实例/静态方法传递给路由,如下所示 class HomeController { public static function index($req, $resp){} } 然后将函数传递给路由 $app->ge

我正在使用Slim框架创建一个API。目前,我使用单个文件创建路由并向其传递闭包:

$app->get('/', function($req, $resp){
//Code...
})
但我意识到我的档案增长很快。我想做的是使用控制器,所以我将有一个控制器类,只需将实例/静态方法传递给路由,如下所示

class HomeController
{
   public static function index($req, $resp){}
}
然后将函数传递给路由

$app->get('/', HomeController::index);

我尝试了这个方法,但它不起作用,我想知道是否有一种方法可以使用它来管理我的文件。

将控制器变成函子:

class HomeController
{
    public function __invoke($req, $resp) {}
}
然后像这样走:

$app->get('/', HomeController::class);
有关参考,请参阅

PHP5.6 Slim 2.6.2

require 'vendor/autoload.php';

class HelloController {
    public static function index()  {
        global $app;

        echo "<pre>";
        var_dump($app->request);
        echo "</pre>";
    }
}

$app = new \Slim\Slim();
$app->get('/', 'HelloController::index');
$app->run();

看起来不像纯类那么漂亮,但在无需额外编码即可访问所有功能的情况下都能像预期的那样工作。

Nikic的快速路由是一个非常简单的路由器,因此,更大框架的一些细节被删除。以下是一个基本解决方案:

routes.php

namespace MyApp;

use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;

require __DIR__ . '/../vendor/autoload.php';

$app->get('/myroute', [new Controller\MyClass, 'get']); // <=== that is pretty short  and neat
$app->post('/myroute', [new Controller\MyClass, 'post']);
$app->map(['GET', 'POST'], '/myotherrout', [new Controller\MyOtherClass, 'run']);
控制器 使用\Psr\Http\Message\ServerRequestInterface作为请求; 使用\Psr\Http\Message\ResponseInterface作为响应

namespace MyApp\Controller;

class MyClass{

    public function __construct(){
       //some code
    }

    public function get(\Slim\Http\Request $request, \Slim\Http\Response $response, $args = []) {
       //some super foobar code
    }

    public function post(\Slim\Http\Request $request, \Slim\Http\Response $response, $args = []) {
       //some other code
    }

将控制器用作对象的简单方法(非静态方法)

在index.php中

控制器\MyClass通过使用PSR自动加载来解决

在Controller/MyOtherClass中:

下面是一个例子:

控制器
哪个文件夹用于添加控制器?如果您将slim\application子类化并将路由文件包含在其中,则可以在整个路由配置中一致使用$this。我在这里还添加了一个示例,它可能有一个将应用程序作为构造函数的路由配置类dependency@Roman当您使用适当的名称空间和composer时,您不需要自己调用require(),因为autoload.php将为您完成这项工作。非常好!谢谢如何在不使用容器的情况下直接将服务注入控制器?虽然这样做有效,但控制器实例的创建应该在依赖项容器注册中完成。我看到您将$logger传递给控制器,而不是传递容器吗?@crafter将容器传递给控制器是一种糟糕的做法。看到了,我听到了。您是对的,该容器太大,无法拖到类中。
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;

$app->get('/', function($req, $resp, $args) use ($app){return FooBar::asdf($app, $req, $resp);});
class FooBar{
    static public function asdf(Slim\App $app, Request $req, Response $resp, $args = [])
    {
        return $resp->withJson(['asf']);
    }
}
namespace MyApp;

use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;

require __DIR__ . '/../vendor/autoload.php';

$app->get('/myroute', [new Controller\MyClass, 'get']); // <=== that is pretty short  and neat
$app->post('/myroute', [new Controller\MyClass, 'post']);
$app->map(['GET', 'POST'], '/myotherrout', [new Controller\MyOtherClass, 'run']);
namespace MyApp\Controller;

class MyClass{

    public function __construct(){
       //some code
    }

    public function get(\Slim\Http\Request $request, \Slim\Http\Response $response, $args = []) {
       //some super foobar code
    }

    public function post(\Slim\Http\Request $request, \Slim\Http\Response $response, $args = []) {
       //some other code
    }
namespace MyApp\Controller;

class MyOtherClass{

    public function __construct(){
       //some code
    }

    public function run(\Slim\Http\Request $request, \Slim\Http\Response $response, $args = []) {
       //some amazing foobar code
    }
<?php

use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Log\LoggerInterface;

/**
 * @property LoggerInterface $logger;
 */
class Controller
{
    /**
     * @var LoggerInterface
     */
    protected $logger

    /**
     * @param LoggerInterface $logger
     */
    public function __construct($logger)
    {
        $this->logger = $logger;
    }

    public function action(ServerRequestInterface $request, ResponseInterface $response, $args=[])
    {
        $this->logger->info((string)$request->getUri());
        /* some actions */
        return $response;
    }
}
<?php

use Slim\App;
use Slim\Container;
use Psr\Container\ContainerInterface;

$autoloader = require(__DIR__.'/vendor/autoload.php');

$container = new Container();

$container['logger'] = function($container) {
    return new Logger();
}

$container['some.controller'] = function ($container) {
    /**
     * @var ContainerInterface $container
     */
    $logger = $container->get('logger');

    return new Controller($logger);
};

$app = new App($container);
$app->get('/some/route', 'some.controller:action');

$app->run();