此项目停止维护,带你了解轻框架LazyPHP的特性与优势
[id_24800600[id_854588166]]id_2105366207]

LAZYPHP简介
LazyPHP(以下简称LP)是一个轻框架.
开发这么一个框架,是因为其他框架给予过多。在高压力情形下,ORM会使简单的页面请求处理变得复杂,盘根错节的对象树也会如此,在调试和性能方面会产生反面效果 。
LP运用函数式接口来封装对象,在内部借助面向对象的方式达成代码重用,在外部提供简洁明了的操作函数。开发者即便不理解面向对象也能够很好地使用,这使得一些初级程序员轻易就能开发出健壮的应用。
在数据库等模块加载方面,LP采用LazyLoad方式,借助$GLOBALS实现全局单件,在方便与高效间寻得平衡点,这是LP框架名字中Lazy的由来,LP在新浪大量运用将近3年,每日承载请求达千万级别,因LP易读易学,使用LP的开发者沟通便利,新同事也能快速融入 。
LP3是LP的最新版本,其最主要的调整是重新定义了Layout规则,这么做是为了应对日益增多的Ajax请求,应对日益增多的Mobile请求,应对日益增多的Rest请求 。同样因为这个原因,LP3和之前的版本不兼容,所以我们建议大家在新项目中采用LP3 。
LP3 实例
基于LP3的全平台开源项目 团队效率工具 TeamToy
LP3简明教程
LP是一个轻框架,它只是打算帮你处理掉每个Web应用都需要重新开始的那部分内容,它并不打算成为一个大而全的Lib,我说的真的不是ZendFrameWork 。
LP包含一个FrontController,还有Layout系统,以及20个常用函数。你只需花10分钟去了解这些内容,便能够完全掌握LP。
FRONTCONTROLLER
前端控制器翻译过来叫FrontController(以下简称FC),在LP中,所有动态请求(不包括静态文件)都要经过FC,使用FC的好处是能统一控制全部请求,举例来说,只需在FC中添加几行代码,就能精确控制哪些controller和action不可访问。
LP3的FC可被看成是ROOT/index.php,实际上分发逻辑在_lp/lp.init.php ,所有请求都在此处处理 ,不管是用户登录还是浏览文章 ,在LP上用户访问的页面都是index.php 。
FC依据Controller和Action对请求予以分组,接着调用相应的模块来开展处理。怎样去定义Controller和Action呢?最为简单的方式是将一个数据表对应至一个Controller,而针对这个数据表的相关操作自然而然就变成了Action。
我们会定义一个名为User的Controller,将Login、Logout、Detail当作User的Action。
我们访问LP时,将需要请求的Controller通过参数c传递给FC,同时把Action也通过参数a传递给FC。
/index.php?c=user&a=login
上边这个访问,告知FC去加载名为User的Controller,还要调用名为Login的方法。
在实现方面,Controller被放置在AROOT.controller目录下,它以Class的形式存在,并且Action是这个Class的一个方法。
下边几行伪代码描述了这个其实很简单的过程:
// FC取得参数 $c = $_REQUEST['c'] ; $a = $_REQUEST['a'] ; // controller文件名和Class名 $cont_file = AROOT . ‘controller/’ . $c . ‘/’ . $a . ‘.class.php’; $class_name =$c .’Controller’ ; // 载入文件 require_once( $cont_file ); // 调用方法 $o = new $class_name; call_user_func( array( $o , $a ) );
实际上,编写应用的过程,就是不断添加Controller的过程,也是不断添加Action的过程,并且要把它们实现。
下边是一个Controller Class的样子:
class defaultController extends appController { function __construct() { parent::__construct(); } function index() { $data['title'] = $data['top_title'] = ‘首页’; render( $data ); } }
MVC和LAYOUT
LP遵循MVC模式,其业务逻辑与显示逻辑完全分离,Controller处理业务逻辑,我们用模板处理显示逻辑。
LP的所有模板都放置在AROOT.view下方,在Controller中借助Render函数来对模板进行渲染。
以下是Render函数的伪代码:
function render( $data = NULL , $layout = NULL , $sharp = ‘default’ ) { $layout_file = AROOT . ‘view/layout/’ . $layout . ‘/’ . $sharp . ‘.tpl.html’; @extract( $data ); require( $layout_file ); }
可以看到,Render接受一个$data数组,接着将数组中的数据extract出来,于是原本是$data['user']的数据在模板里就能通过$user访问了。载入模板部分更为简单,仅仅是直接require。这是由于LP直接运用PHP来作为模板的解释引擎。我们建议大家在模板里采用PHP的短标签语法,以此来保持较高的可读性 。
亲,你是鹳狸猿,亲,你是平民,天黑请闭眼
if( $user['level'] >= 9 ): ?>
亲,你是鹳狸猿
else: ?>
亲,你是平民,天黑请闭眼
endif; ?>
上边是一个使用短标签的模板的示例 ,if、foreach都能够如此书写 ,千万不要在模板里使用{} ,否则会使你的模板显得很怪异 。
为了实现模板的重用,我们引入了Layout系统。
来看一个经常遇到的例子,网站头部导航和页脚版权部分的重用。
最简单且最容易想到的处理办法是:把头部保存成header.tpl.html,把页脚保存成footer.tpl.html。之后在模板中直接用include函数载入就行。
这样挺好的,然而当我们需要处理10个模板时,你会发觉每个模板都得去包含页眉和页脚。在这些模板当中,页眉和页脚实际上是不变的,发生变化的是中间的部分。
于是我们为这些相同模板创建一个通用的模板文件,其名为sharpA.tpl.html,在styleA里我们指定好header和footer,接着sharpA依据FC接收到的C和A变量(还记得吧)去加载对应子目录下的模板,如此我们仅需创建C和A对应的模板即可,下边是一个典型的sharp模板。
当一个sharp无法满足需求时 ,我们能够再创建sharpB.tpl.html 。styleB能够选择性地共享sharpA的header和footer ,也能够载入自身特定的header 。我们将sharpA ,sharpB等通用模板放置到一个目录下 ,称其为一个Layout 。
目前Layout依据访问方式划分成Web、Ajax、Mobile和Rest这四种。当你为游戏机或者电视机创建一组特定风格的sharp模板时,你能够创建一个名为TV或者PFP的Layout目录。
切换Sharp和Layout十分简便,只需改动Render函数里的第二和第三个参数即可。在未指定的情形下,LP3会启用Layout下的default sharp模板,并且会依据请求的方式,自动加载Web,Mobile或者Ajax Layout。
再回过头来说MVC,我们已经了解了C和V在LP的使用情况。M是一个过程,它根据请求参数,从数据库或者其他地方取得数据。在LP3之前,数据是直接在Controller中查询数据库获取的。
function show() { $uid = intval($_REQUEST['uid']); if( $uid < 1 ) return info_page(‘错误的uid’); $data['user'] = get_line( “SELECT * FROM `user` WHERE `uid` = ‘” . $uid . “‘ LIMIT 1″ ); render( $data ); }
这种方式会使SQL分散于各个Action里,这对重用和修改不利。故而在LP3中,我们运用专门的model文件来放置Controller里用到的数据操作函数。仍以上述例子来说,我们假定这是一个名为User的Controller的Show Action。那么在LP3中我们推荐的做法如下:
首先,在AROOT/model目录下进行操作,创建一个文件,该文件名为user.function.php 。
然后在文件中写入获取用户信息的函数:
function get_user_info_by_id( $uid ) { return get_line( “SELECT `name` ,`email` , `bod` FROM `user` WHERE `uid` = ” . intval($uid) . ” LIMIT 1 ” ) }
当请求参数包含?c=user时,user.function.php会自动加载。所以我们能够把show改成下边的模样:
function show() { $uid = intval($_REQUEST['uid']); if( $uid < 1 ) return info_page(‘错误的uid’); $data['user'] = get_user_info_by_id( $uid ); render( $data ); }
在其他的Action中,比如User/settings,我们能够重用代码,借助get_user_info_by_id函数。通过函数封装重复SQL存在一个好处,即方便对SQL进行统一处理,加手工Cache是一个经常会遇到的需求。
常用函数
LP3中的函数主要有3类,分别是迅捷函数、功能函数和数据库函数,这些函数一共有20个左右。
迅捷函数
迅捷函数是一系列的函数缩写:
function c( $str ),用于读取配置文件中,以$str作为key所对应的value 。 function v( $str ),它用于取得 $_REQUEST[$str] 的数据,即便不存在也不会报warning 。 定义一个名为z的函数,该函数接受一个名为$str的参数,其功能是去除字符串中的HTML和PHP标签 。 function g( $str ),用于取得数据,该数据为 $GLOBALS[$str] 所对应的数据。 function t( $str ) // trim 定义一个名为u的函数,该函数接受一个参数$str,其功能是进行urlencode编码 。
功能性函数
定义一个名为render的函数,该函数有三个参数,分别为$data,其默认值为NULL,$layout,其默认值为NULL,$style,其默认值为‘default’,此函数用于布局 定义一个名为info_page的函数,该函数接受一个参数$info,用于系统提示信息 定义一个名为ajax_echo的函数,该函数接受一个参数$info,其作用是输出提示信息,并且包含永不过期的header 。 载入位于lib目录下的文件,使用function uses( $file )
数据库函数
定义一个名为s的函数,该函数有两个参数,分别是$str和$db ,其中$db的默认值为NULL ,此函数的功能等同于mysql_real_escape_string 。 function prepare( $sql, $array ),其作用是将数组中的变量顺序替换SQL中的? 使用config目录下的数据库设置,创建数据库链接,返回数据库链接。 该函数名为get_data,有两个参数,分别是$sql和$db,其中$db默认为NULL,该函数会以二维数组的方式返回$sql对应的结果。 该函数名为get_line,接受两个参数,分别是$sql和$db,其中$db默认为NULL,其功能是以一维数组的方式返回$sql对应的单行结果。 该函数用于以变量的方式返回一个数值,其名为get_var,接受两个参数,分别是$sql和$db,其中$db的默认值为NULL 。 定义一个名为last_id的函数,该函数带有一个参数$db,其默认值为NULL,作用是获取最后一个ID 。 运行sql,不返回结果集,该函数名为run_sql,它接受两个参数,分别是$sql和$db,其中$db默认值为NULL 。 函数名为db_error,用于表示数据库错误信息。 函数名为db_errno,其作用是获取数据库错误编号。 定义一个名为close_db的函数,该函数带有一个参数$db,其作用是显式关闭数据库链接。
特别说明
其中要详细说明的有两个:
C($KEY)和配置文件
LP把应用配置信息保存在AROOT/config/app.config.php下,它用$GLOBALS['config']超全局变量以数组形式来保存这些信息,通过c($key)的方式,能在MVC的各个地方获取这些信息。
PREPARE()函数
这个函数是在LP3中被新引入的,其主要目的在于减少SQL注入的问题,它的使用方式如下:
你提供的内容存在语法错误,正确的应该是:echo $sql = prepare("SELECT * FROM `user` WHERE `name` =?s AND `uid` =?i AND `level` =?s LIMIT 1", array("Easy'", '-1', '9.56')); 以下是改写后的内容:先执行prepare函数,其参数为一个SQL查询语句,该语句用于从`user`表中查询数据,条件是`name`等于?s,`uid`等于?i,`level`等于?s,并且限定结果为1条记录,同时传递一个包含三个值的数组作为参数,最后将执行结果赋值给$sql并输出 。 但需要注意的是,原内容中的语法错误可能会导致实际执行出现问题 。
输出结果为:
从名为`user`的表中进行查询,查询条件是`name`等于‘Easy\’,并且`uid`等于‘-1’,同时`level`等于’9.56’,取第一条记录。
使用prepare函数时要注意,SQL必须使用双引号,【?i】表示整数,【?s】表示整数以外的其他值,prepare会无例外的对内容进行mysql_real_escape_string处理,然后在两边加上单引号。
CSS,JAVASCRIPT和AJAX
LP3采用了一个流行的前端框架BootStrap,关于它的详细介绍,你能够在这里看到。
在JavaScript库方面,LP3开始更换为JQuery ,这里是JQuery API的参考手册 。
为了让不熟悉的同学也能很好地使用Ajax,LP3自行实现了Ajax传输数据的JS函数,这些函数放置在AROOT/static/script/app.js中。
$(‘#标签ID’).load(‘URL’); 它由JQuery自身来实现,能够方便地在不刷新页面的情况下载入页面。 send_form_in( ‘FROMID’ ); 把form表单里的数据提交,借助Ajax进行提交(file类型除外),还要把服务器返回的HTML显示在Form表单顶部。 send_form_pop(‘FROMID’); 将form表单里的数据通过Ajax提交,这里的数据不包括file类型,然后把服务器返回的HTML显示在浮动图层中。
好了,这里涵盖了LP3的所有内容,期望LP3能够助力你更迅速地完成工作。