完整的手册请参考 Hymie PHPMVC framework 手册
版本号 | 说明 |
---|---|
v1.0 | 实现MVC 框架、BeanFactory、路由、过滤器等功能 |
v1.1 | 实现通过注解方式配置路由 |
v1.2 | 1. 修改缓存工厂实现 2. 增加 APCu 缓存 3. 修改 BeanFactory、Router、Filter 默认缓存 |
为 APCu 缓存 4. 调整 Router 处理方式 5. 调整清理缓存方法 |
|
v2.0.2 | 增加 twig delimiter 配置 |
v2.0.5 | 控制器文件名需要以 Controller.php 结尾 |
Hymie PHPMVC 是一个轻量级 MVC 框架,实现中借鉴了 webpy 的一些设计思路。Hymie 的目标是实现基本的 MVC 模式,规范化的开发目录结构约定,并且易于整合和使用第三方库、框架。Hymie 框架代码文件大小约为 270KB。
框架遵循以下 PSR 标准:
PSR-2
PSR-4
PSR-6
PSR-16
如果有改进建议或 BUG 反馈,请联系 mahaixing@gmail.com
web_root
指的是 web
应用的主目录
document_root
指的是 Apache 的 DocumentRoot
或者 nginx 的 root
。
composer require hymie/mvc
代码中引用 config.php
即可完成框架配置
可以从 github 或者 gitee 下载源码使用框架,下载后需要把框架目录放到 web_root
下。
git clone https://github.com/mahaixing/hymie-mvc
git clone https://gitee.com/mahaixing/hymie-mvc
保存下载的目录到项目主目录,代码中需要手工注册 Hymie 的 autoload,用于加载框架类。
<?PHP
// index.php
require '[web_root]/hymie/src/Loader.php';
\hymie\Loader::registerHymieClasses();
require 'config.php';
如果使用 1.2 源码安装则需配置 composer.json
以获取依赖包,以下为依赖配置部分
"require": {
"php": "^7.1",
"catfan/medoo": "^1.7",
"doctrine/annotations": "^1.7",
"mobiledetect/mobiledetectlib": "^2.8",
"monolog/monolog": "^1.24",
"predis/predis": "^1.1",
"symfony/cache": "^3.4",
"twig/twig": "^2.11",
"voku/anti-xss": "^4.1",
"webmozart/assert": "^1.4",
"filp/whoops": "^2.4"
}
将以上部分放到 composer.json
文件后,执行 composer intall
命令完成依赖安装。
composer 安装很慢的话,可以使用 阿里云 Composer 全量镜像
hymie -+
|--- docs --- api (api文档)
|--- src (源代码)
|--- tests (单元测试代码)
|--- .gitignore
|--- composer.json
|--- config.bean.sample.php (bean 配置示例)
|--- config.filter.sample.php (过滤器配置示例)
|--- config.router.sample.php (路由配置示例)
|--- config.sample.php (配置文件示例)
|--- hymie (hymie 脚本,如果 composer 安装可以 ./vendor/bin/hymie 调用)
|--- phpunit.xml (phpunit 测试套件编排文件)
--- README.md
在 document_root
下新建目录 mkdir example
并进入目录 cd example
执行命令:
composer require hymie/mvc
./vendor/bin/hymie copy .
web
./vendor/bin/hymie add web .
index.php
并放入以下内容<?PHP
require 'config.php';
$app = new \hymie\Application(['web']);
$app->run();
现在的项目目录结构
document_root
|
+ -- example
|
|-- app -+
| |
| - web -+
| |- bean (可选)
| |- controller (可选)
| |- service (可选)
| |- view (必须, 默认的模块模板路径)
| |- filter (可选)
| |- dao (可选)
| |- config.filter.php (过滤器配置, 可选)
| - config.router.php (路由配置, 可选)
|-- index.php (入口文件)
|-- config.php (配置文件)
-- config.bean.php (bean 配置文件)
新建 `app/web/controller/IndexController.php' 并放入以下内容
<?PHP
// app/web/controller/IndexController.php
namespace web\controller;
class IndexController
{
public function index()
{
$msg = 'hello world';
return result()->add("msg", $msg)->setView("index")->success();
}
}
新建 app/web/view/index.php
并放入以下内容
<!-- app/web/view/index.php -->
<html>
<head>
<title>example index</title>
</head>
<body>
<h1><?PHP echo $msg;?></h1>
</body>
</html>
修改 app/web/config.router.php
添加路由
```
<?PHP
// config.router.php
return array(
'/' => 'web\controller\IndexController'
);
```
访问浏览器地址 http://localhost/example/index.php
, ok 大功告成。
Hymie 框架开发过程需要大量(至少在路由、过滤器定义中)使用正则表达式,使用正则表达式定义路由可以在一定程度上减少 xss 和 sql 注入类型攻击(参考: 路由部分的 PathVariable 介绍)。
另外,正则表达式也是每个程序员均应该掌握的基本能力。
Hymie 框架使用 PHP pcre 相关函数处理正则表达式,具体请参考 PCRE。
Hymie 框架实现了 MVC 设计模式:
前端控制器 ------> 具体控制器 ----> Service -----> Dao
| ^ | ^ | ^ |
| | | | | | |
| (view)-------- (业务数据)-- (data)<----
|
渲染视图
|
|
v
浏览器
前端控制器是应用入口,Hymie 框架允许使用多个前端控制器,比如 index.php
是站点 web 端前端控制器,admin.php
是后前端控制器口,api.php
为接口前端控制器。
控制器为遵循 PSR-4 规范的 PHP 类,控制器默认的方法为 index
。控制器方法可以有参数,参数需要与路由定义的正则表达式匹配,如果表达式中包含可选的匹配项时,参数需要有默认值。
Service 用来实现业务逻辑。控制数据库事务。Service 为遵循 PSR-4 规范的 PHP 类,在控制器中直接实例化 Service 类即可。
Service 使用具体类即可,其实无必要使用类似于
ServiceInterface
ServiceImpl
这种方式。 所以,不建议使用 bean 工厂来管理 Service 类,配置工作量太大,而且对于大部分业务来说,其实也没有必要做过多解耦。
建议使用 PDO
或者 Medoo
来处理数据库操作,配合框架提供的分页能力,可以很容易完成数据操作、分页等业务需求。分页请参考相关章节。
目前框架支持 json
、php
、twig
三种视图。在配置文件中可以配置默认视图(参考配置章节),视图也可以混用(参考视图章节)。如果请求是 ajax 请求,则会默认返回 json 视图。
框架支持用户自定义视图,在配置文件中注册即可,详细参考视图章节。
视图唯一的要求就是需要在 view_root 目录下按照模块名组织目录,每个模块目录下必须有
view
子目录用来存放视图文件。
控制器执行后可以返回 \hymie\Result
对象,\hymie\Result
对象支持链式调用,并且如果是 ajax 请求的话, json 视图会根据 \hymie\Result
对象组织 json 数据。
如果控制器不返回 \hymie\Result
对象,那么控制器需要自行输出数据到浏览器或者使用 R($to)
函数跳转网页。
支持两种 URL 模式,PATHINFO 和 QueryString,在 config.php
中的 url
部分进行配置。url
配置会影响到 \hymie\Url
类生成链接的方式。
注: nginx 需要进行配置才能支持 PATHINFO,请参考 服务器配置示例部分
注: 如果要生成 url_rewrite 的 url, 需要在配置文件的
url
部分设置url_rewrite
= true
框架支持两种路由配置方式:
return array(
'/' => '[module_dir_name]\controller\IndexController:someMethod',
// 分页, 支持
// http://example.com/index.php?g=/a/1/10 (第1页,每页10条)
// http://example.com/index.php?g=/a/1 (第1页,每页条数使用默认值10条)。
'/product/list/(\d+)(?:(?:/)(\d+))?' => ['mod1\controller\ProductController', 'list'],
*/);
use hymie\annotation\RouterMapping;
/**
* @RouterMapping(value="/(\w*)")
*/
class SomeController
{
public function index($name)
{
// handle path '/abc' '/def' /ghi
// $name = "abc" or "def" or "ghi"
}
}
use hymie\annotation\RouterMapping;
/**
* @RouterMapping(value="/other")
*/
class SomeOtherController
{
public function index()
{
// handle path '/other'
}
/**
* @RouterMapping(value="/foo-(\d{1,3})")
*/
public function login($number)
{
// handle path '/other/foo-1" "/other/foo-123"
// $number = 1 or $number = 123
//could not handle '/ohter/foo-1234'
}
}
过滤器针对配置的路由进行过滤,支持正则表达式匹配路由,支持正则表达式匹配特定路由地址的排除。
当请求后过滤器会以链式方式逐个匹配路由,如不匹配或者匹配后过滤器方法返回 true 则由下一个过滤器继续处理。
当路由无法通过过滤器逻辑,过滤器可使用 R($to)
函数跳转页面,也可直接返回 \hymie\Result
对象。
过滤器是按照定义顺序执行的,因此定义多个过滤器时要注意顺序。
框架中提供 Bean 工厂能力,在 config.bean.php
中配置 bean 信息,由 bean 工厂负责实例化对象。
bean 工厂支持的配置:
bean 间依赖:
beana 依赖 beanb
循环依赖(有条件):
beana 依赖 beanb,且 beanb 也依赖 beana
构造函数:
通过构造函数创建对象实例
工厂方法:
通过工厂方法创建对象实例
属性赋值:
为对象实例属性赋值(public、private、protected 实例都可赋值)
函数调用:
实例创建后要执行的函数
配置文件中配置的 bean 默认是单例的
bean 工厂可以直接根据类名创建类实例。
通过类名创建的类实例默认不是单例的,可以在调用
get_bean
方法时指定是否需要单例实例。
bean 工厂详细信息请参考 bean 工厂章节
Hymie 框架基于适配器模式提供了通用的分页能力,分页主类为 \hymie\pager\Pager
通过该类的工厂方法 public static function getPager($adapterObjOrClassName, ...$params)
创建实例。
分页类在 $_GET $_POST $_REQUEST 中查找 config.php
配置文件中指定的分页参数 p
页数 s
每页数据条数获取分页参数。
目前分页类支持 \PDO
以及 Medoo
分页适配器。
对于 \PDO
适配器已实现 Mysql
SQL 方言,其他数据库类型后续会逐步完成。
具体请参考分页章节。
框架的缓存部分支持 PSR-6 PSR-16 标准缓存库,会将所有 PSR-6 缓存适配为 PSR-16 缓存接口,框架实现了
ArrayCache
基于数组的缓存,在单次请求中有效
ApcuCache
基于 APCu 的缓存,单台服务器实例有效。
Psr6Adapter
适配 PSR-6 缓存实现到 PSR-16 接口规范
Cache
工厂框架通过 Cache
工厂来为应用和框架本身生产缓存实例,工厂方法原型为:
public static function getInstance(
$beanNameOrClassName = self::DEFAULT_BAEN_NAME,
$replaceBeanNameOrClassName = null,
$useBeanFactory = false,
$cleanable = false
)
其中:
$beanNameOrClassName
: 要初始化的缓存 bean
名或者类名。
$replaceBeanNameOrClassName
: 如果要初始化的缓存 bean
或类无法加载,则替换的缓存实现,默认是 ArrayCache
如果替换缓存实现也无法加载,则最终会返回 ArrayCache
实例,以保证使用缓存的代码无需做过多可用性判断,以及可测试性。
$useBeanFactory
: 是否使用 BeanFactory,默认是 true,否则会直接 new 类
$cleanable
: 是否可清理,默认是否,如果为 true 的话会用 \hymie\cache\impl\CleanableCache
包装生成的 bean
Application 启动时会调用 Cache::registerCleaner 函数,在脚本结束时检查 ROOT . DIRECTORY_SEPARATOR .clean_cache 文件,如存在则会清理 CleanableCache 实例。
注意:由于 PSR-6 PSR-16 标准没有遍历所有 key 的方法,因此清理实际上会清除整个缓存,目前框架的
BeanFactory
Router
Filter
是可清理的缓存。
BeanFactory
默认使用ApcuCache
如不可用则会使用ArrayCache
,Router
Filter
默认使用ApcuCache
如不可用则会使用config.bean.php
中配置的缓存实现,默认是系统缓存。 建议启用 php 的apcu
来获取更好的性能
系统日志不能在 config.bean.php
中配置, 因为 BeanFactory
中使用了日志, 会发生递归调用.
日志使用 monolog
, 在 config.php
中进行配置. 若未配置则默认使用 \Psr\Log\NullLogger
, 因此所有输出日志的代码不会出错.
日志配置项参考 config.sample.php
中相关注释.
可以在 config.bean.php
中配置应用要使用的日志 bean.
框架实现了 RedisSession, 可以在 config.php
中配置 $config['session']['redis'] = true;
来开启.
实现类为 \hymie\session\RedisSession
使用 predis 与 redis 交互。默认会在 config.bean.php
中查找名为 predis
的 bean 配置,如未找到则抛出 \hymie\session\SessionException
.
代码中需要使用 start_session()
函数来启动 session, 该函数会根据配置选择启动 php session 或者 redis session. 建议使用此函数来启动session, 而不是内置的 session_start
函数
Web 环境是一个多线程(或进程)的并发环境. 为了保证数据一致性,会对每次页面请求的会话进行加锁. 因此, 需要尽量快的完成 Session 的取值和赋值操作. 这不仅针对 RedisSession 对于其他 Session 实现也适用.
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。