Description

Yet another mini PHP framework.

两个周末,完成了MVC的基本框架,然后加上ORM(或者不加),就可以跑了。

框架是mini的,但是未必是高效的,主要本人编码太渣,纯粹练手。

Feature

  • 使用 Composer 进行包管理,和 app 命名空间管理,详细见composer.json
  • \YAMini\core是主流程,主要部分 trait loader,uri,coreException
  • 全局函数get_instance()获取当前控制器单例(如果是直接跑的路由callback那这个就没意义了)
  • \YAMini\controller中插入了trait \YAMini\loader\YAMini\uri
  • \YAMini\loader中实现了加载类实例化工厂,基于static后期绑定的注册器
  • 代码中使用最多的 traitssatic

Documentation

起步

下载解压,打开目录,安装composer,执行 composer update,生成autoloader 和 安装依赖(目前没有依赖),配置rewrite

REWRITE通用写法:

1
2
3
4
5
6
7
8
9
if (-f $request_filename/index.html){
rewrite (.*) $1/index.html break;
}
if (-f $request_filename/index.php){
rewrite (.*) $1/index.php;
}
if (!-f $request_filename){
rewrite (.*) /index.php;
}

测试

http://yourdomain.com/
http://yourdomain.com/home/test
http://yourdomain.com/home/halo

路由配置

文件:app/config/router.php
如果没有任何配置,路由默认会按照URI请求controller::method(),默认controller和默认methodbootstrap中进行配置。

示例:

1
2
3
'/home'               => controllers\Home::index()
'/home/halo' => controllers\Home::halo()
'/home/abcde7834fghi' => new \Exception('Page Not Found',404)

路由配置举例(匹配规则比较糙):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/**
* 路由设置
* @param string|null $method GET/POST/HEAD/OPTION...* 任选
* @param string|null $pattern 正则表达式
* @param callable|null|string $handler callback function or URI Rewrite
*/
$_app->router($method = 'GET/POST/HEAD',$pattern = null, $handler = null)

//根目录
$_app->router('GET/POST','^\/$', function(){
echo "Home Page!";
});

//匹配所有路径
$_app->router('*','^\/(.*)$', function(){
echo "Site Cloesed!";
});

//REWRITE /home/数字 到 /home/index/数字
$_app->router('GET','^\/home\/(\d+)$', '/home/index');

//匹配 /homework /home* 的
$_app->router('GET','^\/who(.*)$', '/home');

//默认参数,控制器中同理
$_app->router('GET','^\/home\/welcome\/(.*)$', function($name){
printf("welcome %s! \n%s",$name,date('Y-m-d H:i:s'));
});

控制器基本写法

简介
控制器需要在 app/controllers 目录下,可以继承(或者不继承)\YAMini\controller(代码在/core` 下,在composer.json中有 PSR-4配置 )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//controllers/home.php
namespace controllers;
use \YAMini\controller as controller;
class Home extends controller
{
public function index()
{
$data = [
'title' => 'YAMini::Home',
'tpl_name' => 'tpl_home_index',
];

$this->load_view('tpl_layout',$data);
}
}

视图的加载方式

1.使用「布局模板文件」加载

在控制器中使用 $this->load_view(),然后在 layout 中使用 include

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//controllers/home.php
namespace controllers;
use \YAMini\controller as controller;
class Home extends controller
{
public function index()
{
$data = [
'title' => 'YAMini::Home',
'tpl_name' => 'tpl_home_index',
];

$this->load_view('tpl_layout',$data);
}
}

//views/tpl_layout.php
<?include 'tpl_header.php';?>
<?include rtrim($tpl_name,VIEW_EXT).VIEW_EXT;?>
<?include 'tpl_footer.php';?>
2.在控制器中「加载多个视图」

在控制器中通过多次 load_view() 加载多个视图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//controllers/home.php
namespace controllers;
use \YAMini\controller as controller;
class Home extends controller
{
public function index()
{
$data = [
'title' => 'YAMini::Home',
'tpl_name' => 'tpl_home_index',
];

$views = [
'tpl_header',
'tpl_home_index',
'tpl_footer',
];
$this->load_view($views,$data);
/*
* 另外一种繁琐的写法
* $this->load_view('tpl_header' ,$data);
* $this->load_view('tpl_home_index' ,$data);
* $this->load_view('tpl_footer' ,$data);
*/
}
}

模板

开什么玩笑,PHP不就是写前端的么

模型创建

传说中Laravel使用的Eloquent ORM 很赞,所以这里我们也尝试使用它。

测试代码参考: controller\Home::halo()

Eloquent ORM 使用方法可以参考 Laravel 文档

连接数据库:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/*
*config/database.php
*
*/
//使用 default 配置连接数据库
$this->load_db();
$this->load_db('default');

//使用 dev 配置连接数据库
$this->load_db('dev');

//当然你也可以这样
//查询 master 配置中数据库的 users
$this->load_db('master');
$this->load_model('user_model');
$users = $this->user_model->all();
foreach ($users as $user) {
var_dump($user->id);
var_dump($user->name);
}

//查询 slave 配置中数据库的 users
$this->load_db('slave');
$this->load_model('user_model');
$users = $this->user_model->all();
foreach ($users as $user) {
var_dump($user->id);
var_dump($user->name);
}

配置文件加载

代码见:loader::config($filename)
直接读取 config 目录下地该 $filename 的配置返回,参考config/database.php

常见代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/**
* controller
*/
//trait loader
//load view
loader::load_view($files = null,$data = [],$return = false);
$this->load_view('tpl_home_index');
$this->load_view(['tpl_header','tpl_home','tpl_footer']);

//load model
//$_files 可以为数组,此时别名设置无效
$this->load_model($_files = null, $_alias = null);
$this->load_lib($_files = null, $_alias = null);

//class loaded
$this->class_loaded();
$this->is_loaded($class);

//trait uri
//uri array
$this->params($start = 1)
//uri associated array
$this->params_assoc($start = 3)
//uri segment
$this->segment($n = 1)
//uri string
$this->request_uri();

//view
//view 下的 $that 是 get_instance() 获得的实例
$that->load_view('tpl_home_index');

//lib
$that = get_instance();

//默认参数
地址重写前 ,args 默认从第三段 uri 开始,重写后,从匹配项后 开始。

//url 生成
$this->url('home/page1');

//连接数据库
$this->load_db('master');
//数据查询
$this->load_model('user_model');
$users = $this->user_model->all();