PHP Slim Framework创建控制器


PHP Slim Framework Create Controller

我正在使用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);

参考,参见

  • http://www.slimframework.com/docs/objects/router.html#how-创建管线
  • http://www.slimframework.com/docs/objects/router.html#route-回调

PHP 5.6Slim 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');
    });
});

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

平滑&使用控制器作为对象的短方法(不是静态方法)

在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
    }

这里有一个例子:

控制器

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

利润

此方法在文档click me 中有描述

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

routes.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']);
    }
}