Yaf: Yet Another Framework
PHP.net: Yet Another Framework
鸟哥中文文档: Yaf(Yet Another Framework)用户手册
Yaf的优点
天下武功无坚不破,唯快不破
安装/使用
它是通过一个扩展的方式来实现的,我们可以去pecl.php.net去搜索Yaf这个扩展,
我们也可以直接到"http://pecl.php.net/package/yaf"
这里进行访问.
对应自己的系统安装即可: 带beta的是测试版, 带stable版的是稳定版.
跟着这个走即可 安装教程
代码生成工具
1 2 3 4 5 6 7 8
| git clone https:
./php-yaf/tools/cg/yaf_cg yaf-sample
cd ./php-yaf/tools/cg/output/yaf-sample
|
快速入门
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| /----public 公共目录 | |-------index.php 入口文件 | |-------css 样式目录 | |-------img 图片目录 | |-------js 脚本目录 | |----conf 配置目录 | |-------app.ini/application.ini 应用程序配置 | |----app/application 应用程序目录 | |------controllers 控制器目录 | |------views 视图目录 | |------models 模型目录 | |------modules 模块目录 | |------library 类库目录 | |------plugins 插件目录 | |------Bootstrap.php 引导文件 | |----.htaccess 重写文件 #Apache环境下需要, Nginx不需要
|
入口文件
1 2 3 4 5 6 7 8 9 10
| <?php
define("APP_PATH", realpath(dirname(__FILE__).'/../'));
$app = new Yaf_Application(APP_PATH . "/conf/app.ini");
echo $app->bootstrap()->run();
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <?php
date_default_timezone_set("Asia/Shanghai");
if (!defined('__ROOT__')) { $_root = rtrim(dirname(rtrim($_SERVER['SCRIPT_NAME'], '/')), '/'); define('__ROOT__', (('/' == $_root || '\\' == $_root) ? '' : $_root)); }
define("APP_PATH", realpath(dirname(__FILE__).'/../'));
define('APP_ENV', 'dev');
$app = new Yaf_Application(APP_PATH . "/conf/app.ini", APP_ENV);
echo $app->bootstrap()->run();
|
配置文件
或者application.ini, 基于你的入口文件
1 2 3 4 5 6 7
| [common] ;支持直接写PHP中的已定义变量 application.directory = APP_PATH "/app" application.dispatcher.catchException = true
[dev : common] ;yaf.environ = dev
|
控制器
文件名为Index.php,它的首字母是需要大写的,而且该文件中的控制器的类名必须有Controller后缀,
而且去掉后缀后的部分要和文件名保持一直,而且这个类必须继承自Yaf_Controller_Abstract
,而且它里面的所有的动作都必须使用Action后缀。
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
| <?php
class IndexController extends Yaf_Controller_Abstract {
public function indexAction($name = "caoxl") { $get = $this->getRequest()->getQuery("get", "default value");
$model = new SampleModel();
$this->getView()->assign("content", $model->selectSample()); $this->getView()->assign("name", $name);
return TRUE; } }
|
控制器须知
- 每个控制器都需要继承自
Yaf_Controller_Abstract
这个类,它是所有控制器的父类。
- 控制器中的动作都需要加
Action
后缀,比如indexAction,比如readAction等等。
- 需要特殊说明的是,控制器是默认渲染模板的,我们可以通过如下语句来暂时屏蔽这一功能:
1
| Yaf_Dispatcher::getInstance()->disableView();
|
例如:
1 2 3 4 5 6 7 8 9 10 11
| <?php
class StarController extends Yaf_Controller_Abstract { public function starAction() { Yaf_Dispatcher::getInstance()->disableView(); echo "当学习成为一种习惯,进步就是一种必然;"; } }
|
访问: http://yaf.test/star/star
输出: 当学习成为一种习惯,进步就是一种必然;
- 还可以在控制器中定义
init()
方法,它会在每个动作执行之前执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <?php
class GoController extends Yaf_Controller_Abstract { public function init() { Yaf_Dispatcher::getInstance()->disableView(); echo "来自init()方法<br>"; }
public function showAction() { echo "当学习成为一种习惯,进步就是一种必然;"; } }
|
- 在url中使用”控制器/动作名/参数名1/参数值1/参数名2/参数值2…”的格式来请求即可传递参数
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
| <?php
class ParamsController extends Yaf_Controller_Abstract { public function init() { Yaf_Dispatcher::getInstance()->disableView(); }
public function testParamsAction($name, $aim) { echo "您的名字是:".$name."<br/>"; echo "您的目标是:".$aim; }
public function askAction() { $ask = $this->getRequest()->getParam('ask'); $answer = $this->getRequest()->getParam('answer');
echo "您问的问题是:".$ask."<br/>"; echo "您给的答案是:".$answer."<br/>"; } }
|
视图
我们在views目录下新建一个index目录,这个目录中对应的是我们的IndexController
,
该目录下的所有视图文件都是和这个控制器有关系的。然后在index目录中新建一个index.phtml
文件,它对应的是indexAction。
需要说明的是,这个后缀默认应该是phtml
1 2 3
| <?php
echo $content, " I am ", $name;
|
视图须知
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <?php
class TestController extends Yaf_Controller_Abstract { public function indexAction() { $msg = array( 'wife' => '梁超', 'job' => 'PHP' ); $view = $this->getView(); $view->assign('name', '曹贤亮'); $view->assign('msg', $msg); } }
|
我们在views目录下新建一个test目录,然后在里面创建一个index.phtml
文件,然后我们写入如下内容:
1 2 3 4 5 6 7 8 9 10 11
| <!DOCTYPE html> <html> <head> <title><?php echo $name;?></title> </head> <body> <p>您的姓名是:<?=$name?></p> <p>您喜欢的人:<?=$msg["wife"]?></p> <p>您的职位是:<?=$msg["job"]?></p> </body> </html>
|
模型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <?php
class SampleModel { public function __construct() {
}
public function selectSample() { return "Hello Yaf!"; }
public function insertSample($arr) { return true; } }
|
访问: http://yaf.test/index/index
输出: Hello Yaf! I am caoxl
引导文件 Bootstrap.php
我们在app
目录下,可以加一个Bootstrap.php
文件,该文件会在执行控制器之前执行,而且通常我们在该文件中创建一个Bootstrap
类,
继承自Yaf_Bootstrap_Abstract
类,而且该类中带有”_init”前缀的方法都会被自动执行。
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
class Bootstrap extends Yaf_Bootstrap_Abstract { public function _initConfig() {
$arrConfig = Yaf_Application::app()->getConfig(); Yaf_Registry::set('config', $arrConfig); }
public function _initPlugin(Yaf_Dispatcher $dispatcher) { $objSamplePlugin = new SamplePlugin(); $dispatcher->registerPlugin($objSamplePlugin); }
public function _initRoute(Yaf_Dispatcher $dispatcher) { }
public function _initView(Yaf_Dispatcher $dispatcher) { } }
|
不过想让它真正的发挥作用,我们还需要在入口文件中调用bootstrap()方法,即我们的入口文件的代码这么写:
1 2 3 4 5 6 7 8 9 10
| <?php
define("APP_PATH", realpath(dirname(__FILE__).'/../'));
$app = new Yaf_Application(APP_PATH . "/conf/app.ini");
echo $app->bootstrap()->run();
|
配置
我们必须在Yaf_Application
初始化的时候给出配置文件中的配置,其中Yaf的必不可少的配置项只有一个,那就是application.directory
,它表示当前应用程序的绝对路径。
1 2 3 4 5
| [common] application.directory = APP_PATH "/app"
[dev : common] ;yaf.environ = dev
|
其实这个配置项也可以没有,至少从框架层面上做到了”零配置”,但是鸟哥认为,如果一个配置项都没有,就显得太寒酸了,于是就加了这么一个配置项。
除了那个必选的配置项之外,我们还有若干的可选配置项,这些配置项我们都可以在conf目录下的app.ini
文件中进行定义。
application.ext
是php脚本的扩展名,
它的值默认为php,之所以会有这个配置项,是因为很早很早之前,我们也使用”php3”和”php4”作为后缀名,但是现在的文件我们一般都是使用”php”作为后缀名的,因此这个配置项可以忽略
application.bootstrap
是bootstrap文件的绝对路径,也就是我们上面介绍的引导文件,
它通常是在Yaf_Application实例化之后,我们调用它的bootstrap()方法来进行初始化设置。
application.library
是本地类库的绝对路径地址,
它的默认值为应用程序目录下的library目录,该目录下的类库会被自动加载。
application.baseUri
是我们在路由中,需要忽略的路径前缀,
默认值为空,一般不需要设置,Yaf会自动判断。
application.dispatcher.defaultModule
是默认的模块名,默认为index。
application.dispatcher.throwException
是在出错的时候是否抛出异常,默认值为True,表示抛出异常。
application.dispatcher.catchException
是捕获异常用的,
我们一般使用ErrorController的errorAction()来处理这个异常,我们可以通过$request->getException()来获取异常对象。
application.dispatcher.defaultController
是默认的控制器,默认为index。
application.dispatcher.defaultAction
是默认的动作,默认为index。
application.view.ext
是视图模板扩展名,默认为phtml。
application.modules
是存在的模块名,如果我们要定义这个值的话,一定要定义Index模块,默认为Index。
读取配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <?php
class ConfController extends Yaf_Controller_Abstract { public function showAction() { $path = APP_PATH . "/conf/test.ini"; $config = new Yaf_Config_ini($path);
echo "您的姓名是:".$config->test->name."<br/>"; echo "您喜欢的是:".$config->test->love; } }
|
其他配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| [common] application.directory = APP_PATH "/app" application.library.directory = APP_PATH "/library" application.dispatcher.throwException = TRUE application.dispatcher.catchException = TRUE
application.modules = Index,Api,Admin application.view.ext = "phtml"
log_path = APP_PATH "/runtime/logs"
;yaf.environ = dev ;开发配置 [dev : common]
;测试配置 [test : common]
;线上配置 [product : common]
|
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
| [common] ;数据库配置 db.type = "mysql" db.dsn = "" db.hostport = "3306" db.charset = "utf8"
;数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) db.deploy = 0 ;数据库读写是否分类 主从式有效 db.rw_separate = false ;读写分离后主服务器数量 db.master_num = 1 ;指定从服务器序号 db.slave_no = "" ;是否严格检查字段是否存在 db.fields_strict = true ;数据集返回类型 db.resultset_type = 'array' ;自动写入时间戳字段 db.auto_timestamp = false ;时间字段取出后的默认时间格式 db.datetime_format = 'Y-m-d H:i:s' db.sql_explain = false
;线上配置 [product : common] ;是否需要进行SQL性能分析 db.sql_explain = false db.debug = false
;开发配置 [dev : common] db.hostname = "127.0.0.1" db.database = "yaf" db.username = "root" db.password = "root" ;是否需要进行SQL性能分析 db.sql_explain = true db.debug = true db.prefix = "yaf_"
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| [common] ;CORS 跨域设置 Access-Control-Allow-Origin设置 ;['']空,不允许跨站请求 ;['*']允许所有域名不限制来源; ;['http://www.xx.com']允许www.xx.com的跨域请求 ;允许多个域名用[,]隔开 ;开发环境和生产环境可以用不同配置 cors.Access-Control-Allow-Origin = '*'; cors.Access-Control-Allow-Credentials = 'false' ;是否允许跨域使用cookie,'true'允许,false禁止 cors.Access-Control-Allow-Headers = 'x-requested-with,accept,content-type,session-id,token,sessionId,Origin' cors.Access-Control-Allow-Methods = 'GET,POST,PUT,DELETE,OPTIONS' cors.Access-Control-Max-Age = 2592000
;REST 响应设置 rest.param = 'id' ;id形默认绑定参数 如 /User/123 =>绑定参数$id值为123 rest.action = 'info' ;默认绑定控制器如 /User/123 =>绑定到 infoAction rest.none = '_404' ;请求action不存在时调用控制器默认_404Action rest.status = 'err' ;返回数据的状态码字段 rest.data = 'dat' ;返回数据的数据字段 rest.msg = 'msg' ;返回数据的提示信息 rest.error = -1 ;错误状态码 rest.json = JSON_NUMERIC_CHECK|JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES;
|
类库加载
默认来说,类库的目录是app目录下的library目录
比如我们在app
目录下新建一个library
目录,然后我们在改目录中新建一个Tool.php文件,然后我们在里面书写如下代码:
1 2 3 4 5 6 7 8 9
| <?php
class Tool { public function run() { echo "运行Tool类的run方法"; } }
|
那么我们在我们的控制器中就可以这么写:
1 2 3 4 5 6 7 8 9 10
| <?php
class ToolController extends Yaf_Controller_Abstract { public function indexAction() { $tool = new Tool(); $tool->run(); } }
|
插件
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 47
| <?php
class SamplePlugin 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) {
}
public function dispatchLoopStartup(Yaf_Request_Abstract $request, Yaf_Response_Abstract $response) {
}
public function preDispatch(Yaf_Request_Abstract $request, Yaf_Response_Abstract $response) {
}
public function postDispatch(Yaf_Request_Abstract $request, Yaf_Response_Abstract $response) {
}
public function dispatchLoopShutdown(Yaf_Request_Abstract $request, Yaf_Response_Abstract $response) {
} }
|
数据库
这里可以参考thinkyaf
参考