ricardoper / slim4-skeleton
更好的 Slim Framework 4 框架骨架,具有合理的文件夹结构,所有内容均可自定义
Requires
- php: ^7.2
- ext-json: *
- pimple/pimple: ^3.3
- psr/log: ^1.1
- slim/psr7: ^1.1
- slim/slim: ^4.5
- vlucas/phpdotenv: ^4.1
Requires (Dev)
- ricardoper/ddumper: ^1.2
Suggests
- ext-pdo_dblib: For MSSQL or Sybase database on Linux/UNIX platform
- ext-pdo_mysql: For MySQL or MariaDB database
- ext-pdo_oci: For Oracle database
- ext-pdo_oci8: For Oracle version 8 database
- ext-pdo_pqsql: For PostgreSQL database
- ext-pdo_sqlite: For SQLite database
- ext-pdo_sqlsrv: For MSSQL database on both Window/Liunx platform
- catfan/medoo: The Lightweight PHP Database Framework to Accelerate Development
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\Abstracts
的 ControllerAbstract。
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\Message
的MiddlewareInterface。
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\Interfaces
的ResponseEmitterInterface。
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\Abstracts
的ModelAbstract扩展模型。
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\Interfaces
的ServiceProviderInterface。
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"