ricardoper / slim4-twig-skeleton
一个更好的Slim Framework 4骨架,带有Twig,提供合理的文件夹结构,其中一切都可以自定义
Requires
- php: ^7.2
- ext-json: *
- pimple/pimple: ^3.3
- psr/log: ^1.1
- slim/flash: ^0.4.0
- slim/psr7: ^1.1
- slim/slim: ^4.5
- slim/twig-view: ^3.1
- 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视图。用它来快速开始新项目。
注意:如果您想要这个没有Twig的骨架,请访问:https://github.com/ricardoper/slim4-skeleton。
此项目使用PHP Composer 来快速安装,无需任何麻烦。
- PHP >= 7.2
- 易于配置的自定义
- 视图
- 记录器
- 路由
- 处理器
- 中间件
- 配置
- 服务提供者
- 响应发射器
- 错误处理器
- 关闭处理器
- Twig 视图
- 会话
- 控制器
- 全局助手
- PSR-3 用于记录
- 使用 PHP dotenv 的环境变量
- Pimple 作为依赖注入容器
- ddumper 用于开发(基于 Symfony VarDumper)
- 更好的错误处理器(HTML、JSON、XML、纯文本 - 接受 / 内容类型)
- Medoo 数据库框架(MySQL、PostgreSQL、SQLite、MS SQL Server、...)
注意:
- Medoo 是可选的,默认情况下未启用。您可以使用其他库作为服务提供者。如果您想使用此库,请不要忘记安装所需的PDO扩展。
目录
如何安装
从您想安装新Slim Framework v4骨架和Twig视图的目录运行此命令。
composer create-project ricardoper/slim4-twig-skeleton [my-app-name]
注意:
- 将
[my-app-name]
替换为您新应用的所需目录名。 - 确保
storage/
可供Web写入。 - 将您的虚拟主机文档根指向新应用的
public/
目录。
最相关的文件夹
- /app : 应用程序 代码(App 命名空间 - PSR-4)
- ./Controllers : 接受输入并将其转换为模型命令。在此处添加您的 控制器。
- ./Emitters : 根据环境发射响应,包括状态行、头和消息体。在此处添加您的 响应发射器。
- ./Handlers : 处理应用程序的指定行为。在此处添加您的 处理器。
- ./Middlewares : 提供一个方便的机制来过滤进入应用程序的HTTP请求。在此处添加您的 中间件。
- ./Models : 管理应用程序的数据、逻辑和规则。在此处添加您的 模型。
- ./Routes : 将HTTP请求映射到请求处理器(控制器)。在这里添加您的 Routes。
- ./Services : 定义绑定和注入依赖。在这里添加您的 Service Providers。
- ./Views : 任何信息表示,如图表、图表或表格。在这里添加您的 Twig Views。
- /configs : 在这里添加/修改您的 Configurations。
- /public : 在这里添加您的 Assets 文件。
全局助手
env(string $variable, string $default)
- 返回 环境变量(使用DotEnv)app()
- 返回 App 实例container(string $name)
- 从 Container 返回绑定和注入依赖configs(string $variable, string $default)
- 返回 Configs 数据base_path(string $path)
- 返回 基础路径 位置app_path(string $path)
- 返回 app路径 位置configs_path(string $path)
- 返回 configs路径 位置public_path(string $path)
- 返回 public路径 位置storage_path(string $path)
- 返回 storage路径 位置
仅限开发的全局助手
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('/flash', [(new HomeController()), 'flash']); $app->get('/dump', [(new HomeController()), 'dump']); $app->get('/hello/{name}', [(new HelloController()), 'index'])->setName('namedRoute'); $app->get('/addresses', [(new AddressesController()), 'list']); $app->get('/addresses/pdo', [(new AddressesController()), 'pdo']);
控制器
接受输入并将其转换为模型的命令。
您可以在一个干净的方式中添加尽可能多的 Controllers(/app/Controllers
)。
添加您的 Controller 后,您可以在您的 Routes 中启用或禁用它。
注意:要使用助手,必须使用位于 \App\Kernel\Abstracts
的 ControllerAbstract 扩展 Controllers。
use App\Kernel\Abstracts\ControllerAbstract; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; use Twig\Error\LoaderError; use Twig\Error\RuntimeError; use Twig\Error\SyntaxError; class HomeController extends ControllerAbstract { /** * Index Action * * @param Request $request * @param Response $response * @return Response * @throws LoaderError * @throws RuntimeError * @throws SyntaxError */ public function index(Request $request, Response $response): Response { unset($request, $response); return $this->render('Demo/Home/index.twig'); }
控制器助手
getApp()
- 返回 App 对象getContainer(string $name)
- 返回 App ContainergetConfigs(string $name)
- 返回 App ConfigsgetService(string $service)
- 通过名称从容器中返回 ServiceProvidergetRequest()
- 返回 HTTP 请求getResponse()
- 返回 HTTP 响应setEmitter(string $name, string $emitter)
: 设置新的 响应发射器getView()
- 返回 Twig 对象render(string $template, array $data, bool $sendHeaders)
- 渲染 Twig 视图
闪存消息助手
getFlash()
- 返回 Flash Messages 对象setFlashMessage(string $key, $message)
- 设置 Flash MessagehasFlashMessage(string $key)
- 验证Flash Messages的键是否存在getFlashMessages(string $key)
- 获取一个或所有Flash MessagesgetFlashFirstFMessage(string $key, $default)
- 获取键的第一个Flash Messages
视图
您可以以整洁的方式添加任意多的视图(位于/app/Views
)。
您也可以根据需要组织文件夹结构。
我们建议在您的文件中使用twig
扩展以实现代码高亮。
视图助手
url_for()
- 返回给定路由的URL。例如:/hello/worldfull_url_for()
- 返回给定路由的URL。例如:http://www.example.com/hello/worldis_current_url()
- 如果提供的路由名称和参数对当前路径有效,则返回truecurrent_url()
- 返回当前路径,包含或不包含查询字符串get_uri()
- 从传入的ServerRequestInterface
对象返回UriInterface
对象base_path()
- 返回基本路径
您可以使用url_for
生成到任何Slim应用程序命名路由的完整URL,并使用is_current_url
确定是否需要将链接标记为活动状态,如示例Twig模板所示
{% extends "layout.html" %} {% block body %} <h1>User List</h1> <ul> <li><a href="{{ url_for('profile', { 'name': 'josh' }) }}" {% if is_current_url('profile', { 'name': 'josh' }) %}class="active"{% endif %}>Josh</a></li> <li><a href="{{ url_for('profile', { 'name': 'andrew' }) }}">Andrew</a></li> </ul> {% endblock %}
中间件
提供一种方便的机制来过滤进入您应用程序的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 ContainergetConfigs(string $name)
- 返回 App ConfigsgetService(string $service)
- 通过名称从容器中返回 ServiceProvidergetRequest()
- 返回 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
)
- ErrorHandler(默认位于
/app/Handlers/ErrorHandler
) - ShutdownHandler(默认位于
/app/Handlers/ShutdownHandler
)
添加您的处理器后,您可以在configs/app.php
配置文件中启用或禁用它。
use App\Handlers\ShutdownHandler; use Slim\Handlers\ErrorHandler; return [ // Handlers // 'errorHandler' => ErrorHandler::class, 'shutdownHandler' => ShutdownHandler::class,
数据库支持
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
ViewException - For ViewsExceptions
记录
默认启用日志记录,您可以在/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.
/flash - Redirect with Flash Message.
/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"