转自 http://blog.congcong.us/archives/283.html
框架的存在主要意义就是提高程序员的开发效率,同时也带来性能上的一部分损失。
当前开发面向对象已经成为主流,同时为了规范开发使用MVC模式已经成为了一种趋势,当前市面上的框架非常之多,大部分也是MVC模式,但是相对来说对于PHP性能都一定的损失。
那么有没有一种框架既能满足开发效率,又尽可能少的减少性能的损失呢?于是Yaf框架面世。
Yaf是以PHP插件的形式出现,所以少了编译加载等步骤,加强了性能。提供MVC模式,有一定的路由规则,一定的错误处理机制,有一定的触发器。
同时也伴之有不足之处比如说缺少ORM等形式
Yaf的框架搭建的时候目录结构:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public
index.php
.htaccess
css
img
js
conf
application.ini
applciation
controllers
Index.php
views
index
index.phtml
modules
library
models
plugins
|
Yaf的启动
1
2
|
$app
=
new
Yaf_Application(App_PATH.
"/CONF/APPLICATION.INI"
);
$app
->run();
|
配置Yaf的路由规则 开启URL重写
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
RewriteEngine On
RewriteCond ${REQUEST_FILENAME} !-f
RewriteRule .* index.php
server{
listen ***;
server_name domain.com
root document_root;
index index.php index.html index.htm
if
(!-e
$request_filename
){
rewrite ^/(.*) /idnex.php/
$1
last;
}
}
|
SAE下的重写
1
2
3
4
|
name:your_app_name
version:1
handle:
-rewrite:
if
(!
is_dir
() && !
is_file
() && path ~
"^(.*)$"
)
goto
"/index.php"
|
输出HelloWorld
1
2
3
4
5
6
7
|
<?php
class
IndexController
extends
Yaf_Controller_Abstract{
public
function
indexAction(){
$this
->getView()->assign(
"content"
,
"Hello world"
);
}
}
?>
|
1
2
|
[product]
application.driectory = APP_PATH.
"/application/"
|
创建demo
1
|
yaf_cg sample
|
配置文件 至少一个application.directory
其他可选:
1
2
3
4
5
6
7
8
9
10
11
12
|
application.ext php脚本的扩展名
application.bootstrap Bootstrap路径
application.library 类库的绝对目录地址
application.baseUri 在路由中需要忽略的路径前缀
applciation.dispatcher.defaultModule 默认的模块
applciation.dispatcher.throwException 出错的时候抛出异常
applciation.dispatcher.catchException 使用默认的异常捕获Controller
application.dispatcher.defaultController 默认控制器
application.dispatcher.defaultAction 默认动作
appcation.view.ext 视图模板扩展名
appcation.modules 声明存在的模块名,注意如果要定义这个值一定要定义Index Module
application.system.* 通过这个属性,可以修改yaf的runtime configure 比如application.system.lowcase_path,但是请注意只有PHP_INI_ALL的配置项才可以在这里被修改,此选项从2.2.0开始引入
|
自动加载器
Autoloader 目录映射加载MVC类
非框架MVC类 Yaf支持全局类和自身类的两种加载方式 支持大小写敏感和大小写不敏感两种方式
全局类和自身类(本地类)
全局类:指有产品之间共享的类,这些类库的路径是通过ap.library在php.ini
本地类:产品自身的类库,这些类库的路径是通过在产品的配置文件中,通过ap.library配置的
在yaf中,通过调用Yaf_Loader的regiterLocalNamespace方法,来申明那些类前缀是本地类,即可
类加载规则
下划线分割目录信息,Yaf按照目录信息完成自动加载
1
2
|
$loader
= Yaf_Loader::Instance(0);
$loader
->registerLocalNamespace(
array
(
"Foo"
,
"Local"
));
|
Bootstrap 引导程序 提供一个全局配置的入口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
$app
=
new
Yaf_Application(
"conf.ini"
);
$app
->bootstrap()->run();
// _init开头
//这些方法都接受一个参数:Yaf_Dispatcher $dispatcher
//调用顺序按照声明顺序
class
Bootstrap
extends
Yaf_Bootstrap_Abstract{
public
function
_initConfig(){
$config
= Yaf_Application::app()->getConfig();
Yaf_Registry::set(
"config"
,
$config
);
}
public
function
_initDefaultName(Yaf_Dispatcher
$dispatcher
){
$dispatcher
->setDefaultModule(
"Index"
)->setDefaultController(
"Index"
)->setDefaultAction(
"Index"
);
}
}
|
Yaf支持的Hook
routerStartup
routerShutdown
dispatchLoopStartup
preDispatch
posDispatch
dispatchLoopShutdown
自定义插件(可接受两个参数 Yaf_Request_Abstract 和 Yaf_Response_Abstract)
1
2
3
4
5
|
<?php
class
UserPlugin
extends
Yaf_Plugin_Abstract{
public
function
routerStartup(Yaf_Request_Abstract
$request
,Yaf_Response_Abstract
$response
){}
public
function
routerShutdown(Yaf_Request_Abstract
$request
,Yaf_Response_Abstract
$response
){}
}
|
Yaf插件 必须继承自Yaf_Plugin_Abstract plugins目录
路由和路由协议
路由组件有两个部分:路由器(Yaf_Router)和路由协议(Yaf_Route_Abstract).
路由注册的顺序很重要,最后注册的路由协议,最先尝试路由,这就有个陷阱,请注意。
Yaf零基础学习总结1-Yaf框架简介
从今天开始,给大家讲解下yaf框架,讲解之前肯定要了解下yaf是个什么东西,当然,从标题我们已经知道yaf是个PHP框架了,也许大家对于PHP框架并不陌生,一般PHP程序员用过的框架至少有一两个吧,国内用的比较多的有ThinkPHP,YII之类的,用Yaf的还真不多。原因个人感觉有两个,一个是刚推广不久,第二个就是门槛高,让新手无从下手,大多数新手更喜欢用那些使用广泛,教程文档多的框架
首先引用yaf的作者对yaf的一个简单引述:
随着PHP的发展, PHP框架层出不穷, 但到底用不用PHP框架, 还存在很大的争论, 反对者认为使用框架会降低性能, 经常举例的就是Zend Framework. 而支持者则认为,采用框架能提高开发效率, 损失点性能也是值得的.
而这些也正是公司内框架种类繁多的一个原因, 有的项目组为了性能而选择某些框架, 而另外一些项目组, 则为了更好的封装选择了另外的框架
那, 有没有俩全的办法呢? 也就是说, 有没有那么一个框架, 既不会有损性能, 又能提高开发效率呢.
Yaf, 就是为了这个目标而生的.
Yaf有着和Zend Framework相似的API, 相似的理念, 而同时又保持着对Bingo的兼容, 以此来提高开发效率, 规范开发习惯. 本着对性能的追求, Yaf把框架中不易变的部分抽象出来,采用PHP扩展实现(c语言),以此来保证性能.在作者自己做的简单测试中, Yaf和原生的PHP在同样功能下, 性能损失小于10%, 而和Zend Framework的对比中, Yaf的性能是Zend Framework的50-60倍.
可以看出,Yaf框架一个最大的优势就是快,他是用C语言写的,和原生PHP一样,速度快,接近原生的PHP,如同作者而言,剑的三层境界:一是手中有剑,心中亦有剑;二是手中无剑,心中有剑;三是手中无剑,心中亦无剑,在和其他用PHP写的PHP框架来比的话, Yaf就是剑的第二层境界. 框架不在你手中, 而在PHP的"心"中.
官方文档对Yaf的优点做了以下总结
1. 用C语言开发的PHP框架, 相比原生的PHP, 几乎不会带来额外的性能开销.
2. 所有的框架类, 不需要编译, 在PHP启动的时候加载, 并常驻内存.
3. 更短的内存周转周期, 提高内存利用率, 降低内存占用率.
4. 灵巧的自动加载. 支持全局和局部两种加载规则, 方便类库共享.
5. 高性能的视图引擎.
6. 高度灵活可扩展的框架, 支持自定义视图引擎, 支持插件, 支持自定义路由等等.
7. 内建多种路由, 可以兼容目前常见的各种路由协议.
8. 强大而又高度灵活的配置文件支持. 并支持缓存配置文件, 避免复杂的配置结构带来的性能损失.
9. 在框架本身,对危险的操作习惯做了禁止.
10. 更快的执行速度, 更少的内存占用
默认情况下路由器是Yaf_Router 默认路由协议 Yaf_Route_Static 基于Http路由的,他期望一个请求时Http请求并且请求对象是使用yaf_Request_Http
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
|
<?php
//路由器实例
$router
= Yaf_Dispatcher::getInstance()->getRouter();
//路由器协议
$router
->addRoute(
'myRoute'
,
$route
);
在配置文件中定义:
[common]
;自定义路由 顺序很重要
routes.regex.type=
"regex"
routes.regex.match =
routes.regex.route.controller = Index
routes.regex.route.action = action
routes.regex.map.1 = name
routes.regex.map.2 = value
;添加一个名为simple的路由协议
routes.simple.type=
"simple"
routes.simple.controller = c
routes.simple.module = m
routes.simple.action = a
;添加一个名为supervar的路由协议
routes.supervar.type =
"supervar"
routes.supervar.varname = r
[product:common]
;product节是Yaf默认关心的节,添加一个名为rewrite的路由协议
routes.rewrite.type =
"rewrite"
routes.rewrite.match =
"/product/:name/:value"
<?php
class
Bootstrap
extends
Yaf_Bootstrap_Abstract{
public
function
_initRoute(Yaf_Dispatcher
$dispatcher
){
$router
= Yaf_Dispatcher::getInstance()->getRouter();
//添加配置中的路由
$router
->addConfig(Yaf_Registry::get(
"config"
)->routes);
}
}
|
//其实路由器也提供给我们不同的方法来得到和设置包含在它内部的信息,一些重要的方法如下:
getCurrentRoute() //在路由结束以后, 获取起作用的路由协议
getRoute(), getRoutes();//看函数基本意思也就知道.
自定义路由器:申明你的路由协议实现了Yaf_Route_Interface接口即可
异常和错误
application.dispatcher.throwException 打开的情况下 会抛异常,否则会触发错误
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<?php
class
ErrorController
extends
Yaf_Controller_Abstract{
publi
function
errorAction(
$exception
){
//NO1.
assert(
$exception
===
$exception
->getCode());
$this
->getView()->assign(
"code"
,
$exceptioon
->getCode());
$this
->getView()->assign(
"message"
,
$exception
->getMessage());
//NO.2
$exception
=
$this
->getRequest()->getException();
try
{
throw
$exception
;
}
catch
(Yaf_Exception_LoadFailed
$e
) {
//加载失败
}
catch
(Yaf_Exception
$e
) {
//其他错误
}
}
}
|