simsoft/slim

为 Slim 框架提供的一个优秀的路由包装器

1.0.3 2024-08-28 12:41 UTC

This package is auto-updated.

Last update: 2024-09-28 13:04:37 UTC


README

slim/slim 提供的一个优秀的包装器。

安装

composer require simsoft/slim

基本用法

在 index.php 或任何入口脚本文件中设置以下代码。有关创建路由教程,请参阅 Slim 路由

<?php
declare(strict_types=1);
require_once 'vendor/autoload.php';

use Simsoft\Slim\Route;
use Slim\App;
use function Simsoft\Slim\response;

// Usage example
Route::make()
    ->withErrorHandler(false, true, true)
    ->withRouting(fucntion(App $app) {
        $app->get('/', function() {
            response('Hello World!');
        });

        $app->get('/{name}', function(string $name) {
            response("Hello $name!");
        });
    })
    ->run();

启用缓存

Route::make()
    ->withErrorHandler(false, true, true)
    ->withRouting(
        routes: fucntion(App $app) {
            $app->get('/', function() {
                response('Hello World!');
            });

            $app->get('/{name}', function(string $name) {
                response("Hello $name!");
            });
        },
        cachePath: '/path/to/routes.cache', // Commit the cache file for production.
    )
    ->run();

中间件

有关中间件教程,请参阅 Slim 中间件

<?php
declare(strict_types=1);
require_once 'vendor/autoload.php';

use Simsoft\Slim\Route;
use Slim\App;
use function Simsoft\Slim\response;

Route::make()
    ->withErrorHandler(false, true, true)
    ->withMiddleware(function(App $app) {

        $app->add(function($request, $handler) {
            $response = $handler->handle($request);
            $response->getBody()->write('Welcome');
            return $response;
        });

    })
    ->withRouting(
        routes: fucntion(App $app) {
            $app->get('/', function() {
                response('Hello World!');
            });

            $app->get('/{name}', function(string $name) {
                response("Hello $name!");
            });
        },
        cachePath: '/path/to/routes.cache', // Enable cache. Commit the cache file for production.
    )
    ->run();

与容器一起使用

Slim 路由支持任何 ContainerInterface 容器。

<?php
declare(strict_types=1);
require_once 'vendor/autoload.php';

use DI\ContainerBuilder;
use Psr\Container\ContainerInterface;
use Simsoft\Slim\Route;
use Slim\App;
use function Simsoft\Slim\response;

$containerBuilder = new ContainerBuilder();

$containerBuilder->addDefinitions([
    'logger' => function(ContainerInterface $c) {
        return new \Your\Namespace\CustomLogger();
    }
]);

$container = $containerBuilder->build();

Route::make($container)
    ->withErrorHandler(false, true, true)
    ->withMiddleware(function(App $app) {

        $app->add(function($request, $handler) use ($app) {
            $response = $handler->handle($request);
            $app->getContainer()->get('logger')->info('Use container log service.');
            return $response;
        });

    })
    ->withRouting(fucntion(App $app) {
        $app->get('/{name}', function(string $name) use ($app) {
            $app->getContainer()->get('logger')->info('Use container log service.');
            response("Hello $name!");
        });
    })
    ->run();

使用控制器

The App\AppController.php
<?php
namespace App;

use function Simsoft\Slim\response;

class AppController
{
    public function index()
    {
        response('Hello World');
    }

    public function name(string $name)
    {
        response("Hello $name!");
    }

    /**
     * Return string will display text immediately.
     * @return string
     */
    public function showText(): string
    {
        return 'Display text';
    }

    /**
     * Return array will display JSON immediately.
     * @return array
     */
    public function getJson(): array
    {
        return [1, 2, 3, 4, 5];
    }
}
The index.php 入口脚本文件。
<?php
declare(strict_types=1);
require_once 'vendor/autoload.php';

use App\AppController;
use Simsoft\Slim\Route;
use Slim\App;

Route::make()
    ->withRouting(fucntion(App $app) {
        $app->get('', [AppController::class, 'index']);
        $app->get('/{name}', [AppController::class, 'name']);
        $app->get('/show-text', [AppController::class, 'showText']);
        $app->get('/get-json', [AppController::class, 'getJson']);
    })
    ->run();

使用容器与控制器

The App\AppController.php 文件。
<?php
namespace App;

use Psr\Container\ContainerInterface;
use function Simsoft\Slim\response;

class AppController
{
    public function __construct(protected ContainerInterface $container)
    {
    }

    public function index()
    {   // call container service.
        $this->container->get('logger')->info('Log information');

        response('Hello World');
    }

    public function name(string $name)
    {
        response("Hello $name!");
    }
}
The index.php 入口脚本文件
<?php
declare(strict_types=1);
require_once 'vendor/autoload.php';

use App\AppController;
use DI\ContainerBuilder;
use Simsoft\Slim\Route;
use Slim\App;

$containerBuilder = new ContainerBuilder();

$containerBuilder->addDefinitions([
    'logger' => function(ContainerInterface $c) {
        return new \Your\Namespace\CustomLogger();
    }
]);

$container = $containerBuilder->build();

Route::make($container)
    ->withRouting(fucntion(App $app) {
        $app->get('', [AppController::class, 'index']);
    })
    ->run();

请求和响应使用

处理请求、响应和重定向。

请求方法

有关详细教程,请参阅: Slim 请求教程

<?php
namespace App;

use function Simsoft\Slim\request;

class AppController
{
    public function action1()
    {
        // trigger not found.
        request()->notFound();
        request()->notFound('The resource is not available.');

        request()->getQueryParams();    // return $_GET
        request()->getParsedBody();     // return $_POST
        request()->getUploadedFiles();  // return UploadedFileInterface[]

        // route URL.
        echo request()->urlFor('route_name')
        //output: /url-slug

        echo request()->urlFor('route_name', queryParams: ['a' => 1, 'b' => 2])
        //output: /route_name?a=1&b=2

        if (request()->isXHR()) { /**/ }            // Detect is XHR request.
        if (request()->isMethod('post')) { /**/ }   // Detect request method is POST.
    }
}

响应方法。

有关详细教程,请参阅: Slim 响应教程

<?php
namespace App;

use function Simsoft\Slim\response;
use function Simsoft\Slim\request;

class AppController
{
    public function action1()
    {
        // Return text.
        response('Hello World');            // normal display.
        response('Authorized only', 401)    // Display text with status code
        response()->content('Authorized only')->status(401);

        // Return JSON
        $data = ['status' => 'success', 'message' => 'Welcome'];
        response($data);
        response()->json($data);

        // Set header
        response()->header('Content-Type', 'text/html');
        response()->withHeaders([
            'Content-Type' => 'text/html',
            'X-app' => 'Slim route',
        ])

        // Redirect
        response()->redirect('https://www.somedomain.com');   // normal usage.
        response()->redirect('/url-slug', 302);               // redirect with status code
        response()->redirect(request()->urlFor('route_name')) // use with slim route.
        response()->redirectNow('https://www.url.com');       // Perform redirect immediately.
    }
}

创建自定义错误处理器

步骤 1:创建用于 HTML 的自定义错误渲染器。

CustomizedHtmlErrorRenderer 文件。
<?php
namespace App;

use Simsoft\Slim\ErrorRenderers\AbstractHtmlErrorRenderer;
use Throwable;

class CustomizedHtmlErrorRenderer extends AbstractHtmlErrorRenderer
{
    public function renderHtmlBody(Throwable $exception): string
    {
        // write your own HTML body
        return strtr('<html lang="en">
                    <header>
                        <title>{{ code }} {{ title }}</title>
                    </header>
                    <body>
                        {{ message }} <br />
                        {{ description }}
                    </body>
                    </html>', [
                '{{ code }}' => $exception->getCode(),
                '{{ title }}' => $this->getErrorTitle($exception),
                '{{ message }}' => $exception->getMessage(),
                '{{ description }}' => $this->getErrorDescription($exception),
            ]);
    }
}

步骤 2:在 CustomizedErrorHandler 类中相应地应用自定义错误渲染器类。

CustomizedErrorHandler 文件
<?php
namespace App;

use App\CustomizedHtmlErrorRenderer;
use Slim\Error\Renderers\JsonErrorRenderer;
use Slim\Error\Renderers\PlainTextErrorRenderer;
use Slim\Error\Renderers\XmlErrorRenderer;
use Slim\Handlers\ErrorHandler;
use Slim\Interfaces\ErrorRendererInterface;

class CustomizedErrorHandler extends ErrorHandler
{
    protected $defaultErrorRenderer = CustomizedHtmlErrorRenderer::class; // use CustomizedHtmlErrorRenderer

    /**
     * @var ErrorRendererInterface|string|callable
     */
    protected $logErrorRenderer = PlainTextErrorRenderer::class;

    protected array $errorRenderers = [
        'application/json' => JsonErrorRenderer::class,
        'application/xml' => XmlErrorRenderer::class,
        'text/xml' => XmlErrorRenderer::class,
        'text/html' => CustomizedHtmlErrorRenderer::class, // use CustomizedHtmlErrorRenderer
        'text/plain' => PlainTextErrorRenderer::class,
    ];
}

步骤 3:使用 withErrorHandler() 方法设置自定义ErrorHandler。

The index.php 入口脚本文件。
<?php
declare(strict_types=1);
require_once 'vendor/autoload.php';

use App\CustomizedErrorHandler;
use Simsoft\Slim\Route;
use Slim\App;
use function Simsoft\Slim\response;

Route::make()
    ->withErrorHandler(false, true, true, errorHandlerClass: CustomizedErrorHandler::class)
    ->withRouting(fucntion(App $app) {
        $app->get('/{name}', function(string $name){
            response("Hello world!");
        });
    })
    ->run();

许可协议

Simsoft 验证器采用 MIT 许可协议。有关详细信息,请参阅 LICENSE 文件