最近想建一个网站,试了很多CMS,有dedeCMS 及PHPCMS 等,无奈功能都太强,虽然都有很大自由可以作二次开发,但是学习这些CMS二次开发的成本,比自己制定一个刚好满足自己需要的还要大!犹豫许久,昨晚才彻底决定放弃实用CMS!
今天上班不用干活,无奈,花一个下午看了LazyPHP3的代码!
(一)
LazyPHP3是一个小巧的PHP MVC框架,由新浪 @easy 主导的一个项目,可以在一般的PHP主机上使用,也支持新浪云计算平台,LP只包含一个FrontController+Layout系统+20个常用函数,非常容易就可以掌握,当然,对初学者而言,这个框架最郁闷的估计就是缺少实例了。
LazyPHP3详细简介请查看:http://ftqq.com/lazyphp/
LazyPHP3的下载地址在GitHub :https://github.com/easychen/LazyPHP 打开后直接点Downloads即可下载整个项目。
项目文件及功能如下:
01 | LazyPHP |
02 | │ index.php //项目入口文件 |
03 | │ README.md //LazyPHP说明文件,Markdown格式 |
04 | │ |
05 | ├─config //项目配置 |
06 | │ app.config.php //项目配置文件 |
07 | │ db.config.php //项目数据库配置文件 |
08 | │ |
09 | ├─controller //项目逻辑控制所在文件夹 |
10 | │ app. class .php //类 |
11 | │ default . class .php //项目默认控制器 |
12 | │ |
13 | ├─lib //项目函数库 |
14 | │ app. function .php //函数库 |
15 | │ |
16 | ├─local //项目本地化配置 |
17 | │ zh_cn.lang.php //中文 |
18 | │ |
19 | ├─model //项目模块 |
20 | │ README //说明,空文件 |
21 | │ |
22 | ├─view //项目页面显示模板(详细文件列表略) |
23 | │ |
24 | ├─ static //项目静态文件,包括css,js代码及图像. |
25 | │ |
26 | ├─test //JSUnit及PHPUnit测试框架文件(详细文件列表略) |
27 | │ |
28 | └─_lp //LazyPHP3框架 |
29 | │ lp.init.php //框架入口 |
30 | │ st.init.php //可能是SAE版框架的入口 |
31 | │ |
32 | ├─core //框架核心 |
33 | │ ├─config |
34 | │ │ core.config.php //框架配置文件 |
35 | │ │ |
36 | │ ├─controller |
37 | │ │ core. class .php //框架逻辑控制类 |
38 | │ │ |
39 | │ ├─lib |
40 | │ │ core. function .php //核心函数库 |
41 | │ │ db. function .php //数据库操作函数 |
42 | │ │ db.sae. function .php //sae数据库操作函数 |
43 | │ │ |
44 | │ ├─model //模块 |
45 | │ │ README |
46 | │ │ |
47 | │ └─view //框架默认模板(详细文件列表略) |
48 | │ |
49 | └─simpletest //框架测试文件(详细文件列表略) |
在这里先要强调一点,我们从GitHub网站上所下载的这些文件,其实是一个基于LazyPHP3框架写出来的网站,将这些文件放到PHP服务器就可以直接运行了,而LP3框架的核心文件在则是在这个项目的“_lp”文件夹内!
(二)
现在,我们来看一下这个基于LazyPHP的网站是如何运行的,先从网站的入口(根目录下的index.php)开始:
index.php的主要代码如下:
1 | /**** load lp framework ***/ |
2 | define( 'DS' , DIRECTORY_SEPARATOR ); //DIRECTORY_SEPARATOR是PHP里的一个内置命令,用来将解决Win与Linux下的路径区分问题 |
3 | define( 'AROOT' , dirname( __FILE__ ) . DS ); //这里定义的AROOT是网站所在根目录,而不是LP框架所在根目录 |
4 |
5 | //ini_set('include_path', dirname( __FILE__ ) . DS .'_lp' ); // |
6 | include_once ( '_lp' .DS . 'lp.init.php' ); //载入LP框架的_lp文件夹内的lp.init.php文件 |
7 | /**** lp framework init finished ***/ |
在定义网站根目录地址给常量AROOT后,随即载入LazyPHP3框架初始化文件lp.init.php,我们跟过去看一下:
lp.init.php文件主要做了4件事:
1、定义:定义框架根目录、框架核心目录,并设置PHP报错级别:
01 | if ( !defined( 'AROOT' ) ) die ( 'NO AROOT!' ); |
02 | if ( !defined( 'DS' ) ) define( 'DS' , DIRECTORY_SEPARATOR ); |
03 |
04 | // define constant |
05 | define( 'IN' , true ); |
06 |
07 | define( 'ROOT' , dirname( __FILE__ ) . DS ); //定义框架根目录 |
08 | define( 'CROOT' , ROOT . 'core' . DS ); //定义框架核心目录 |
09 |
10 | // define |
11 | error_reporting (E_ALL^E_NOTICE); //设置 PHP 的报错级别 |
12 | ini_set ( 'display_errors' , true ); |
2、载入:载入框架及网站核心函数,载入框架及网站配置:
1 | include_once ( CROOT . 'lib' . DS . 'core.function.php' ); //载入框架核心函数 |
2 | @ include_once ( AROOT . 'lib' . DS . 'app.function.php' ); //载入网站函数 |
3 |
4 | include_once ( CROOT . 'config' . DS . 'core.config.php' ); //载入框架配置 |
5 | include_once ( AROOT . 'config' . DS . 'app.config.php' ); //载入网站配置 |
3、解析判断:解析请求并判断是否存在对应处理类及方法:
01 | //下面两句代码对请求的网址做判断,如果没有类和方法请求,就由default_controller调用default_action |
02 | $c = $GLOBALS [ 'c' ] = v( 'c' ) ? v( 'c' ) : c( 'default_controller' ); |
03 | $a = $GLOBALS [ 'a' ] = v( 'a' ) ? v( 'a' ) : c( 'default_action' ); |
04 |
05 | $c = basename ( strtolower ( z( $c ) )); |
06 | $a = basename ( strtolower ( z( $a ) )); |
07 |
08 | $post_fix = '.class.php' ; |
09 |
10 | $cont_file = AROOT . 'controller' . DS . $c . $post_fix ; |
11 | $class_name = $c . 'Controller' ; |
12 | if ( ! file_exists ( $cont_file ) ) //判断是否存在类文件 |
13 | { |
14 | $cont_file = CROOT . 'controller' . DS . $c . $post_fix ; |
15 | if ( ! file_exists ( $cont_file ) ) die ( 'Can\'t find controller file - ' . $c . $post_fix ); |
16 | } |
17 |
18 |
19 | require_once ( $cont_file ); //当存在对应的类文件时,LP立马将该文件载入,然后才有下面的判断 |
20 | if ( ! class_exists ( $class_name ) ) die ( 'Can\'t find class - ' . $class_name ); //判断是否存在类 |
21 |
22 |
23 | $o = new $class_name ; |
24 | if ( !method_exists( $o , $a ) ) die ( 'Can\'t find method - ' . $a . ' ' ); //判断是否存在相应类方法 |
25 |
26 |
27 | if ( strpos ( $_SERVER [ 'HTTP_ACCEPT_ENCODING' ], 'gzip' ) !== FALSE) ob_start( "ob_gzhandler" ); |
4、最后,根据请求调用对应类的方法:
1 | call_user_func( array ( $o , $a ) ); //通过call_user_func调用$o 类里面的 $a 方法。 |
现在我们假定我们的请求地址是:http://localhost/lazyphp/?a=index ,看在经过lp.init.php文件的处理后,我们会跑去哪里!
首先,请求地址里没有指定参数c的值,在lp.init.php中c将被赋值为函数c('default_controller')的返回值,即'default'(对应值在框架核心配置文件core.config.php内设置),a的值则为'index'。
也就是说,lp.init.php文件执行到最后,将调用defaultController类的index方法。
打开LazyPHP/controller 目录下的default.class.php 文件,看一下defaultcontroller类的index方法:
01 | include_once ( AROOT . 'controller' .DS. 'app.class.php' ); |
02 |
03 | class defaultController extends appController |
04 | { |
05 | function __construct() |
06 | { |
07 | parent::__construct(); |
08 | } |
09 | |
10 | function index() |
11 | { |
12 | $data [ 'title' ] = $data [ 'top_title' ] = '首页' ; |
13 | render( $data ); |
14 | } |
15 | //此处省去N行代码 |
16 | } |
defaultController类的index方法看起来非常简单,不过是设置了数组$data['titile']的值为'首页',然后就调用render()函数,并将数组$data作为调用参数。那render($data)函数究竟做了什么?
1、判断调用何种Layout,Layout系统是LazyPHP的一个特色!我暂时没用过,还未弄清楚具体用法和特性,具体用法及特点请参看LazyPHP简介。
01 | function render( $data = NULL , $layout = NULL , $sharp = 'default' ) |
02 | { |
03 | if ( $layout == null ) |
04 | { |
05 | if ( is_ajax_request() ) |
06 | { |
07 | $layout = 'ajax' ; |
08 | } |
09 | elseif ( is_mobile_request() ) |
10 | { |
11 | $layout = 'mobile' ; |
12 | } |
13 | else |
14 | { |
15 | $layout = 'web' ; //默认是采用layout文件夹里的web文件夹内模板 |
16 | } |
17 | } |
18 | //此处省去N行代码 |
19 | } |
2、接下来render()函数释放出$data数据内的数据,并通过php的require()函数载入对应的模板,此时原先$data数组中的数据都可以在模板内使用。
01 | function render( $data = NULL , $layout = NULL , $sharp = 'default' ) |
02 | { |
03 | //此处省去N行代码 |
04 | |
05 | $GLOBALS [ 'layout' ] = $layout ; |
06 | $GLOBALS [ 'sharp' ] = $sharp ; |
07 | $layout_file = AROOT . 'view/layout/' . $layout . '/' . $sharp . '.tpl.html' ; |
08 | if ( file_exists ( $layout_file ) ) |
09 | { |
10 | @extract( $data ); |
11 | require ( $layout_file ); |
12 | } |
13 | else |
14 | { |
15 | $layout_file = CROOT . 'view/layout/' . $layout . '/' . $sharp . '.tpl.html' ; |
16 | if ( file_exists ( $layout_file ) ) |
17 | { |
18 | @extract( $data ); |
19 | require ( $layout_file ); |
20 | } |
21 | } |
22 | } |
被载入的网页模板,在执行模板内的php语句后最终显示出来。
以上就是LazyPHP框架的大概执行流程。