4

我正在使用 Slim 框架创建一个 API。目前我使用单个文件来创建路由并将闭包传递给它:

$app->get('/', function($req, $resp){
//Code...
})

但我意识到我的文件增长迅速。我想做的是改用控制器,所以我将有一个控制器类,只需将实例/静态方法传递给路由,如下所示

class HomeController
{
   public static function index($req, $resp){}
}

然后将函数传递给路由

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

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

4

5 回答 5

11

将控制器变成函子:

class HomeController
{
    public function __invoke($req, $resp) {}
}

然后像这样路由:

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

供参考,请参阅

于 2015-12-31T00:15:59.517 回答
3

PHP 5.6 超薄 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();

更新: PHP 5.6 Slim 3.0.0

require 'vendor/autoload.php';

class HelloController {
    public static function hello(\Slim\Http\Request $req, \Slim\Http\Response $response, $args)  {
        echo "<pre>";
        var_dump($args);
        echo "</pre>";
    }
}

$app = new \Slim\App();
$app->get('/hello/{name}', 'HelloController::hello');
$app->run();

Slim 3.0 中基于类的路由的问题是访问$this/ $app。我认为您将需要使用global $app它来访问它。

在我的宠物项目中,我使用带有require_once. 就像是

$app->group('/dashboard', function () {
    $this->group('/auctions', function () use ($app){
        require_once('routes/dashboard/auctions.php');
    });
    $this->group('/rss', function () {
        require_once('routes/dashboard/rss.php');
    });
    $this->group('/settings', function () {
        require_once('routes/dashboard/settings.php');
    });
});

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

于 2015-12-31T00:43:34.160 回答
2

这是一个例子:

控制器

<?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();

利润!

这种方法在文档中有描述点击我

于 2018-04-19T09:39:27.917 回答
2

将控制器用作对象的平滑且简短的方式(不是静态方式)

在 index.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']);

在控制器/MyClass 中:

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
    }

Controller\MyClass 是通过使用 PSR 自动加载来解决的

在控制器/MyOtherClass 中:

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
    }
于 2018-02-06T10:18:23.920 回答
1

Nikic 的 Fast Route 是一个非常小的路由器,因此删除了较大框架的一些细节。这是一个基本的解决方案:

路由.php

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);});

控制器使用 \Psr\Http\Message\ServerRequestInterface 作为请求;使用 \Psr\Http\Message\ResponseInterface 作为响应;

class FooBar{
    static public function asdf(Slim\App $app, Request $req, Response $resp, $args = [])
    {
        return $resp->withJson(['asf']);
    }
}
于 2017-07-16T11:37:51.207 回答