ricardoper/slim4-skeleton

更好的 Slim Framework 4 框架骨架,具有合理的文件夹结构,所有内容均可自定义

v2.2.0 2020-05-25 11:46 UTC

This package is auto-updated.

Last update: 2024-08-25 21:46:39 UTC


README

一个超级组织(具有合理的文件夹结构)且非常可自定义的 Slim Framework v4 骨架。使用它来快速开始新的项目。

注意:如果您想使用 Twig 的这个骨架,请访问:(https://github.com/ricardoper/slim4-twig-skeleton)。

此项目使用 PHP Composer 以快速安装,无需任何麻烦。

  • PHP >= 7.2
  • 可通过简单的配置进行自定义
    • 日志记录器
    • 路由
    • 处理器
    • 中间件
    • 配置
    • 服务提供者
    • 响应发射器
    • 错误处理器
    • 关闭处理器
  • 会话
  • 控制器
  • 全局辅助工具
  • PSR-3 用于日志记录
  • 使用 PHP dotenv 的环境变量
  • Pimple 作为依赖注入容器
  • ddumper 用于开发(基于 Symfony VarDumper
  • 更好的错误处理器(JSON、XML、PlainText - 接受 / 内容类型)
  • Medoo 数据库框架(MySQL、PostgreSQL、SQLite、MS SQL Server、...)

备注:

  • 会话中间件 默认未启用。
  • Medoo 是可选的,默认未启用。您可以使用其他库作为服务提供者。如果您想使用此库,请务必安装所需的 PDO 扩展。

目录

安装方法

在您想要安装新的 Slim Framework v4 骨架的目录中运行此命令。

composer create-project ricardoper/slim4-skeleton [my-app-name]

注意:

  • [my-app-name] 替换为您新应用程序希望使用的目录名称。
  • 确保 storage/ 可供网络写入。
  • 将您的虚拟主机文档根目录指向新应用程序的 public/ 目录。

最相关的文件夹

  • /app : 应用程序 代码(App 命名空间 - PSR-4
    • ./Controllers : 接受输入并将其转换为模型命令。在此处添加您的 控制器
    • ./Emitters : 根据环境发送响应,包括状态行、标头和消息主体。在此处添加您的 响应发射器
    • ./Handlers : 处理应用程序的指定行为。在此处添加您的 处理器
    • ./Middlewares : 提供一种方便的机制,用于过滤进入应用程序的 HTTP 请求。在此处添加您的 中间件
    • ./Models : 管理应用程序的数据、逻辑和规则。在此处添加您的 模型
    • ./Routes : 将 HTTP 请求映射到请求处理器(控制器)。在此处添加您的 路由
    • ./Services : 定义绑定和注入依赖。在此处添加您的 服务提供者
  • /configs : 在此处添加/修改您的 配置
  • /public : 在此处添加您的 资源 文件

全局辅助工具

  • env(string $variable, string $default) - 返回 环境变量(使用 DotEnv)
  • app() - 返回 App 实例
  • container(string $name) - 从 容器 返回绑定和注入依赖
  • configs(string $variable, string $default) - 返回 Configs 数据
  • base_path(string $path) - 返回 基本路径 位置
  • app_path(string $path) - 返回 app路径 位置
  • configs_path(string $path) - 返回 配置路径 位置
  • public_path(string $path) - 返回 公共路径 位置
  • storage_path(string $path) - 返回 存储路径 位置

仅供开发使用的全局助手

  • d($var1, $var2, ...) - 默认以折叠模式显示变量
  • ddd($var1, $var2, ...) - 默认以折叠模式显示并终止程序
  • de($var1, $var2, ...) - 默认以展开模式显示变量
  • dde($var1, $var2, ...) - 默认以展开模式显示并终止程序

配置

您可以添加任意数量的配置文件(/configs)。这些文件将根据所选环境自动预加载并合并到容器中。

如果您有一个名为 "sandbox" 的环境,并且只想为此环境覆盖一些配置,您需要在 /configs 中创建一个子文件夹 "sandbox"。例如 /configs/sandbox。然后创建一个包含您需要替换的配置以及相应的键和值的文件。

/configs/logger.php

return [

    'name' => 'app',

    'maxFiles' => 7,

];

/configs/local/logger.php

return [

    'name' => 'app-local',

];

环境的 name 结果

  • prod : 'app'
  • sandbox : 'app'
  • local : 'app-local'
  • testing : 'app'

注意:您可以在框架中查看 local 环境的示例。

配置点表示法

您可以使用 点表示法 从配置中获取值。

/configs/example.php

return [

    'types' => [
        'mysql' => [
            'host' => 'localhost',
            'port' => '3306',
        ],
        'postgre' => [
            'host' => 'localhost',
            'port' => '3306',
        ],
    ],

];

如果您需要 MySQL 类型的 host

$this->getConfigs('example.types.mysql.host')  => 'localhost'

configs('example.types.mysql.host') => 'localhost'

container('configs')->get('example.types.mysql.host') => 'localhost'

路由

将 HTTP 请求映射到请求处理器(闭包或控制器)

您可以在 /app/Routes 中添加任意数量的路由文件,但您需要在 /apps/Routes/app.php 文件中启用这些文件。

您可以根据自己的喜好组织这些路由。这里有一个小示例,您可以看到如何组织这些文件。

use App\Controllers\Demo\AddressesController;
use App\Controllers\Demo\HelloController;
use App\Controllers\Demo\HomeController;
use Slim\App;

/**
 * @var $app App
 */

$app->get('/', [(new HomeController()), 'index']);

$app->get('/dump', [(new HomeController()), 'dump']);

$app->get('/hello/{name}', [(new HelloController()), 'index'])->setName('namedRoute');

$app->get('/addresses', [(new AddressesController()), 'list'])->setName('namedRoute');

$app->get('/addresses/pdo', [(new AddressesController()), 'pdo'])->setName('namedRoute');

控制器

接受输入并将其转换为模型命令。

您可以以整洁的方式添加任意数量的 控制器/app/Controllers)。

添加您的 控制器 后,您可以在 路由 中启用或禁用它。

注意:要使用助手,您必须将 控制器 扩展到位于 \App\Kernel\AbstractsControllerAbstract

use App\Kernel\Abstracts\ControllerAbstract;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;

class HomeController extends ControllerAbstract
{

    /**
     * Index Action
     *
     * @param Request $request
     * @param Response $response
     * @return Response
     */
    public function index(Request $request, Response $response): Response
    {
        unset($request, $response);

        $data = ['Hello' => 'World!'];

        return $this->json($data);
    }

控制器助手

  • getApp() - 返回 App 对象
  • getContainer(string $name) - 返回 App 容器
  • getConfigs(string $name) - 返回 App 配置
  • getService(string $service) - 通过名称从容器返回 服务提供者
  • getRequest() - 返回 HTTP 请求
  • getResponse() - 返回 HTTP 响应
  • setEmitter(string $name, string $emitter) : 设置新的 响应发射器
  • write(string $data) - 发送到输出
  • json(array $data, bool $sendHeaders) - 发送 JSON 编码 到输出

中间件

提供一种方便的机制来过滤进入您应用程序的 HTTP 请求。

您可以以整洁的方式添加任意数量的 中间件/app/Middlewares)。

在添加您的中间件后,您可以在configs/middlewares.php配置文件中启用或禁用它。

注意中间件必须遵循位于\Psr\Http\MessageMiddlewareInterface

use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\MiddlewareInterface as Middleware;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;

class ExampleMiddleware implements Middleware
{

    /**
     * Process an incoming server request.
     *
     * Processes an incoming server request in order to produce a response.
     * If unable to produce the response itself, it may delegate to the provided
     * request handler to do so.
     *
     * @param Request $request
     * @param RequestHandler $handler
     * @return Response
     */
    public function process(Request $request, RequestHandler $handler): Response
    {
        $response = $handler->handle($request);

        $response = $response->withHeader('X-Example', 'Middleware');

        return $response;
    }
}

configs/middlewares.php中启用它

use App\Middlewares\Demo\ExampleMiddleware;

return [

    'example' => ExampleMiddleware::class,

];

响应发射器

根据环境,发出响应,包括状态行、头信息和消息主体。

您可以在/app/Emitters中以整洁的方式添加任意多的响应发射器

添加您的响应发射器后,您可以在configs/emitters.php配置文件中全局启用或禁用它,或者您可以在控制器中为特定操作添加它。

注意响应发射器必须遵循位于\App\Kernel\InterfacesResponseEmitterInterface

use App\Kernel\Interfaces\ResponseEmitterInterface;
use Psr\Http\Message\ResponseInterface;

class JsonResponseEmitter implements ResponseEmitterInterface
{

    /**
     * Send the response to the client
     *
     * @param ResponseInterface $response
     * @return ResponseInterface
     */
    public function emit(ResponseInterface $response): ResponseInterface
    {
        $response = $response
            ->withHeader('Content-Type', 'application/json; charset=UTF-8');

        return $response;
    }
}

configs/emitters.php中启用它

use App\Emitters\JsonResponseEmitter;

return [

    'json' => JsonResponseEmitter::class,

];

模型

管理应用的数据、逻辑和规则。

您可以在/app/Models中以整洁的方式添加任意多的模型

添加您的模型后,您可以在例如控制器中使用它。

注意:为了有助手,您必须使用位于\App\Kernel\AbstractsModelAbstract扩展模型

use App\Kernel\Abstracts\ModelAbstract;
use PDO;

class AddressesModel extends ModelAbstract
{

    /**
     * Get Last Addresses with Pdo
     *
     * @param int $limit
     * @return array
     */
    public function getLastWithPdo(int $limit = 25): array
    {
        /** @var $db PDO */
        $db = $this->getDb()->pdo;

        $sql = 'SELECT `address`.`address_id`,`address`.`address`,`address`.`address2`,`address`.`district`,`city`.`city`,`address`.`postal_code`,`address`.`phone` FROM `address` ';
        $sql .= 'LEFT JOIN `city` ON `address`.`city_id` = `city`.`city_id` ';
        $sql .= 'ORDER BY `address_id` DESC LIMIT 10';

        return $db->query($sql)->fetchAll(PDO::FETCH_ASSOC);
    }

模型辅助工具

  • getApp() - 返回 App 对象
  • getContainer(string $name) - 返回 App 容器
  • getConfigs(string $name) - 返回 App 配置
  • getService(string $service) - 通过名称从容器返回 服务提供者
  • getRequest() - 返回 HTTP 请求
  • getResponse() - 返回 HTTP 响应
  • getDb() - 返回数据库对象

服务提供者

定义绑定并注入依赖。

您可以在/app/Services中以整洁的方式添加任意多的服务提供者

添加您的服务提供者后,您可以在configs/services.php配置文件中启用或禁用它。

注意服务提供者必须遵循位于\App\Kernel\InterfacesServiceProviderInterface

use App\Kernel\Interfaces\ServiceProviderInterface;
use Pimple\Container;

class ExampleServiceProvider implements ServiceProviderInterface
{

    /**
     * Service register name
     */
    public function name(): string
    {
        return 'example';
    }

    /**
     * Register new service on dependency container
     *
     * @param Container $container
     * @return mixed
     */
    public function register(Container $container)
    {
        return function (Container $c) {
            unset($c);

            return new Example();
        };
    }
}

configs/services.php中启用它

use App\Services\Demo\ExampleServiceProvider;

return [

    'example' => ExampleServiceProvider::class,

];

处理器

处理应用的指定行为。

您可以在/app/Handlers中以整洁的方式覆盖以下处理器

  • 错误处理器(默认位于/app/Handlers/ErrorHandler
  • 关闭处理器(默认位于/app/Handlers/ShutdownHandler

添加您的处理器后,您可以在configs/app.php配置文件中启用或禁用它。

use App\Handlers\ErrorHandler;
use App\Handlers\ShutdownHandler;

return [

    // Handlers //
    'errorHandler' => ErrorHandler::class,

    'shutdownHandler' => ShutdownHandler::class,

数据库支持

Medoo作为服务提供者内置。使用Medoo是可选的,并且默认未启用。

要使用Medoo启用数据库支持,您需要使用Composer添加此库/供应商

composer require catfan/medoo

安装后,您需要在configs/services.php中启用服务提供者

use App\Services\Database\DatabaseServiceProvider;

return [

    'database' => DatabaseServiceProvider::class,

];

现在您可以开始使用它了...

如果您需要更多详细信息、文档、API参考,请访问Medoo网页:https://medoo.in/

备注:

  • 别忘了为您的数据库加载PDO扩展。例如,如果您需要MySQL,您需要安装pdo_mysql PHP扩展。
  • 您可以使用其他库作为服务提供者(MySQLi、PostgreSQL、MongoDB、Redis等本机驱动程序)。

异常

您有一些内置的异常,位于\App\Kernel\Exceptions,您可以使用它们。

ConfigsException  - For Configurations Exceptions
ModelException    - For Models Exceptions
ServiceException  - For Service Providers Exceptions

日志记录

日志默认启用,您可以在/storage/logs/app-{date}.log中查看所有输出。

您可以在/.env/configs/app.php中设置这些参数。

LOG_ERRORS |  logErrors  (bool)  - Enable/Disable logging.

LOG_ERRORS_DETAILS  |  logErrorDetails  (bool)  - Enable/disable extra details in the logging file.

LOG_TO_OUTPUT  | logToOutput  (bool)  - `true` to output the logs in console, `false` to output logs in file.

调试

调试默认禁用。您可以在/.env/configs/app.php中设置这些参数。

APP_DEBUG  |  displayErrorDetails  (bool)  - Enable/disable debugging.

演示

此骨架包含一个小的示例,您可以在其中看到所有这些操作的实际效果。

示例URL

 /               - Hello World Example.
 /hello/{name}   - Greet User. Replace {name} with your name.
 /addresses      - Database example with Medoo
 /addresses/pdo  - Database example with PDO from Medoo
 /dump           - See the source code of this action.

基准测试

没有免费的东西,所以让我们比较与Slim骨架的性能损失。

机器
Intel® Core™ i5-8400 CPU @ 2.80GHz × 6
16Gb RAM
SSD

版本
Ubuntu 20.04 LTS
Docker v19.03.8
nginx 1.17.10
PHP v7.4.3
Zend OPcache启用
SIEGE 4.0.4

基准详情
25个并发连接
每个线程500个请求
请求之间没有延迟
命令:siege -c25 -b -r500 "URL"


享受简洁性 :oP