Я создаю API, используя Slim Framework. В настоящее время я использую один файл для создания маршрута и передачи ему закрытия:
$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);
Для справки см.
PHP 5.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();
Обновить: 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
}
Быстрый маршрут Nikic — это очень минимальный маршрутизатор, поэтому некоторые тонкости больших фреймворков удалены. Вот основное решение:
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']);
}
}
Вот пример:
<?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();
Этот метод описан в документации нажми на меня