升级指南

最后更新于:2022-04-01 22:33:27

# 升级指南 如果你打算从 Slim 2 升级到 Slim 3,这里有一些重要的变化,你必须清楚。 ## 新的 PHP 版本要求 Slim 3 要求 PHP 5.5+ ## 新的路由函数签名 ``` $app->get('/', function (Request $req, Response $res, $args = []) { return $res->withStatus(400)->write('Bad Request'); }); ``` ## 获取 _GET 和 _POST 变量 ``` $app->get('/', function (Request $req, Response $res, $args = []) { $myvar1 = $req->getParam('myvar'); //检查 _GET 和 _POST [不遵循 PSR 7] $myvar2 = $req->getParsedBody()['myvar']; //检查 _POST [遵循 PSR 7] $myvar3 = $req->getQueryParams()['myvar']; //检查 _GET [遵循 PSR 7] }); ``` ## 钩子 / Hooks Slim v3 不再有钩子的概念。You should consider reimplementing any functionality associated with the [default hooks in Slim v2](http://docs.slimframework.com/hooks/defaults/) as [middleware](/docs/concepts/middleware.html) instead. If you need the ability to apply custom hooks at arbitrary points in your code (for example, within a route), you should consider a third-party package such as [Symfony’s EventDispatcher](http://symfony.com/doc/current/components/event_dispatcher/introduction.html) or [Zend Framework’s EventManager](https://zend-eventmanager.readthedocs.org/en/latest/). ## 移除 HTTP 缓存 在 Slim v3 我们将 HTTP 缓存迁移到了单独的模块中: [Slim\Http\Cache](https://github.com/slimphp/Slim-HttpCache). ## 移除 Stop/Halt Slim Core has removed Stop/Halt. In your applications, you should transition to using the withStatus() and withBody() methods. ## 重定向的改变 在 Slim v2.x 我们需要使用助手函数 $app->redirect(); 来触发重定向请求。在 Slim v3.x 中,我们可以使用响应类来做这事。 Example: ``` $app->get('/', function ($req, $res, $args) { return $res->withStatus(302)->withHeader('Location', 'your-new-uri'); }); ``` ## 中间件签名 中间件的签名已经从一个类变成了函数。 新的签名: ``` use Psr\Http\Message\RequestInterface as Request; use Psr\Http\Message\ResponseInterface as Response; $app->add(function (Request $req, Response $res, callable $next) { // Do stuff before passing along $newResponse = $next($req, $res); // Do stuff after route is rendered return $newResponse; // continue }); ``` 你仍然可以使用类来做签名: ``` namespace My; use Psr\Http\Message\RequestInterface as Request; use Psr\Http\Message\ResponseInterface as Response; class Middleware { function __invoke(Request $req, Response $res, callable $next) { // Do stuff before passing along $newResponse = $next($req, $res); // Do stuff after route is rendered return $newResponse; // continue } } // Register $app->add(new My\Middleware()); // or $app->add(My\Middleware::class); ``` ## Middleware Execution Application middleware is executed as Last In First Executed (LIFE). ## Flash Messages Flash messages are no longer a part of the Slim v3 core but instead have been moved to seperate [Slim Flash](/docs/features/flash.html) package. ## Cookies In v3.0 cookies has been removed from core. See [FIG Cookies](https://github.com/dflydev/dflydev-fig-cookies) for a PSR-7 compatible cookie component. ## Removal of Crypto In v3.0 we have removed the dependency for crypto in core. ## New Router Slim now utilizes [FastRoute](https://github.com/nikic/FastRoute), a new, more powerful router! This means that the specification of route patterns has changed with named parameters now in braces and square brackets used for optional segments: ``` // named parameter: $app->get('/hello/{name}', /*...*/); // optional segment: $app->get('/news[/{year}]', /*...*/); ``` ## Route Middleware The syntax for adding route middleware has changed slightly. In v3.0: ``` $app->get(…)->add($mw2)->add($mw1); ``` ## urlFor() is now pathFor() in the router `urlFor()` has been renamed `pathFor()` and can be found in the `router` object: ``` $app->get('/', function ($request, $response, $args) { $url = $this->router->pathFor('home'); $response->write("Home"); return $response; })->setName('home'); ``` Also, `pathFor()` is base path aware. ## Container and DI … Constructing Slim uses Pimple as a Dependency Injection Container. ``` // index.php $app = new Slim\App( new \Slim\Container( include '../config/container.config.php' ) ); // Slim will grab the Home class from the container defined below and execute its index method. // If the class is not defined in the container Slim will still contruct it and pass the container as the first arugment to the constructor! $app->get('/', Home::class . ':index'); // In container.config.php // We are using the SlimTwig here return [ 'settings' => [ 'viewTemplatesDirectory' => '../templates', ], 'twig' => [ 'title' => '', 'description' => '', 'author' => '' ], 'view' => function ($c) { $view = new Twig( $c['settings']['viewTemplatesDirectory'], [ 'cache' => false // '../cache' ] ); // Instantiate and add Slim specific extension $view->addExtension( new TwigExtension( $c['router'], $c['request']->getUri() ) ); foreach ($c['twig'] as $name => $value) { $view->getEnvironment()->addGlobal($name, $value); } return $view; }, Home::class => function ($c) { return new Home($c['view']); } ]; ``` ## PSR-7 Objects ### Request, Response, Uri & UploadFile are immutable. This means that when you change one of these objects, the old instance is not updated. ``` // This is WRONG. The change will not pass through. $app->add(function (Request $request, Response $response, $next) { $request->withAttribute('abc', 'def'); return $next($request, $response); }); // This is correct. $app->add(function (Request $request, Response $response, $next) { $request = $request->withAttribute('abc', 'def'); return $next($request, $response); }); ``` ### Message bodies are streams ``` // ... $image = __DIR__ . '/huge_photo.jpg'; $body = new Stream($image); $response = (new Response()) ->withStatus(200, 'OK') ->withHeader('Content-Type', 'image/jpeg') ->withHeader('Content-Length', filesize($image)) ->withBody($body); // ... ``` For text: ``` // ... $response = (new Response())->getBody()->write('Hello world!') // Or Slim specific: Not PSR-7 compliant. $response = (new Response())->write('Hello world!'); // ... ```
';