Yaf开发文档

==Yaf开发指南==

===说明===


;本文档仅作为[http://yaf.laruence.com/manual/ http://yaf.laruence.com/manual/]的补充,也会指出一些在使用中容易忽略的地方,以及一些使用技巧
===入口文件===
 
bootstrap()->run();
*入口文件注意3个地方:
**yaf.environ, 该配置属于PHP_INI_SYSTEM,仅在php.ini配置生效。可以配置成你想要的值,默认是product。当用ini作配置文件时,它会使用该值为名的节
**Yaf_Application的构造函数有2个参数。第一个参数是配置项,可以传一个数组,或者一个ini文件的地址。第2个参数是个字符串,传值后如果使用ini文件作为配置,将使用该值对应的节作为配置,默认为yaf.environ的值
**在new Yaf_Application("conf.ini")之后,Yaf_Application::run之前,如果调用Yaf_Application::bootstrap()( 即代码中的$app->bootstrap()->run() ),将会依次执行Bootstrap.php中所有以_init开头的方法



===配置文件===
 
[yaf]
 application.directory=APPLICATION_PATH "/application"
 application.dispatcher.throwException=TRUE
 application.dispatcher.catchException=TRUE
 application.dispatcher.defaultController="site"
 application.dispatcher.defaultAction = "index"
 application.view.ext="php"
 [common : yaf]
 site.title=" 我的官网"
 site.discountMin=100
 site.limitPerOrder=30
*Yaf支持用php和ini两种文件格式的配置文件,其中php文件需返回一个数组,ini文件传入后也会被转换成一个对应的多维数组(实际是一个对象)
*如果使用使用ini作为配置文件,site.title="我的官网" 等效于 array('site'=>array('title'=>"我的官网") )
*代码中[yaf]定义了一个名叫yaf的配置节,[common : yaf]定义了一个叫common的配置节,它继承yaf配置节。
*如果打开yaf.cache_config,ini配置文件将会被缓存




===插件[plugin]===
;插件需要向Yaf_Dispatcher注册才能生效。插件文件放APPLICATION_PATH下的plugins目录下由自动加载器加载,放在其他目录则由普通加载规则加载,详细请参考:[http://yaf.laruence.com/manual/yaf.plugin.html 第7章-使用插件]


===模板[view]===
*Yaf_View_Simple是Yaf自带的视图引擎, 它追求性能,使用纯PHP语法,所以并没有提供类似Smarty那样的多样功能, 和复杂的语法.如果需要使用smarty,也可以替换。
*关于layout
layout对于维护代码是非常必要的,而Yaf本身并没有提供这样的功能。网上的实现一般是通过Yaf的插件机制来实现,
在新版商城中,我们简洁的实现了一套render layout方法。
 
  
//Base_Ctrl所有controller的父类
class Base_Ctrl extends Yaf_Controller_Abstract {
    
    public $layoutfile = 'column_main';
    public $main_view='main';


   public $pageTitle='';                   //页面title
   //等等等等。。。。这些变量可以在view里面通过$C来直接传输和调用


    public function render($phtml,$params=array(),$return=false) {
        $paramsExtra = array_merge($params,array('actionName'=>$this->getActionId(),'controllerName'=>$this->getControllerId()));
        $paramsExtra['C'] = $this;//把controller实例传给view, 方便传一些参数和方法过去
        $html1 = $this->render($phtml,  $paramsExtra);//先渲染action自身的view
        if ( !empty($this->layoutfile) ) {
            //如果需要layout, 则渲染layout
            $html1 = $this->getView()->render(PATH_TPL.'/layout/'.$this->layoutfile.'.php',  array_merge($paramsExtra,array('content'=>$html1)) );
        }
        //最后渲染最外层的公共layout
        $html1 = $this->getView()->render(PATH_TPL.'/layout/'.$this->main_view.'.php',  array_merge($paramsExtra,array('content'=>$html1)));
        if ( $return ) {
            return $html1;
        } else {
            echo $html1;
            exit;
        }
    }
    //这个方法主要用于应对不需要layout的情况
    public function renderPartial($phtml,$params=array(),$return=false) {
        $paramsExtra = array_merge($params,array('actionName'=>$this->getActionId(),'controllerName'=>$this->getControllerId()));
        $paramsExtra['C'] = $this;
        $html1 = $this->render($phtml,$paramsExtra);       
        if ( $return ) {
            return $html1;
        } else {
            echo $html1;
            exit;
        }
    }
}
===路由=== *路由注册的顺序很重要, 最后注册的路由协议, 最先尝试路由, 这就有个陷阱. 请注意. *路由解析仅仅发生一次,某一个路由协议返回成功以后, 就匹配成功 *路由配置好后需要Yaf_Config::addConfig和Yaf_Router::addRoute两种方法来添加路由协议,才会生效 *路由注册示例代码:
class Bootstrap extends Yaf_Bootstrap_Abstract{


    public function _initConfig(){
        Yaf_Registry::set("config",  Yaf_Application::app()->getConfig());
    }
    
    public function _initRoute() {
        $config = Yaf_Registry::get('config');
        $routeconfigs = isset($config['routes']) ? $config['routes'] : array();
        Yaf_Dispatcher::getInstance()->getRouter()->addConfig($routeconfigs);
    }
}





===扩展(此部分非yaf框架自带)===
;商城在对yaf的使用时,引入了一些yii的好的使用起来方便的东西,其使用习惯跟yii基本一样。
*models/BaseForm.php BaseFormModel是一个表单基础类,继承后可使用rules方法来实现验证规则的定义
 
public function rules() {
     return array(
         array('contact, content', 'required'),
     );
 }
*controller中可以跟yii一样使用accessRules方法定义未登录和登录用户对action的访问权限
 public function accessRules() {
     return array(
         array('allow',
             'actions' => array('*'),
             'users' => array('@'),
         ),
     );
 }


*libray/Redis 是一个封装好的redis类,支持单台和多台服务器的常用操作
;使用方法 
 $redis = new Redis_Connection();
 $redis->$key = $value;  //配置
 $redis->get('key');
 //多台服务器
 redis4.class="Redis_Connection"
 redis4.servers.0.host="10.237.2.72"
 redis4.servers.0.port=6379
 redis4.servers.1.host="10.237.2.73"
 redis4.servers.1.port=6379
 //单台服务器
 redis7.class="Redis_Connection"
 redis7.host="10.237.2.72"
 redis7.port=8379




;view中$C是当前contrlloer的实例,对其赋值后可以在页面做相应的展示,如
 $C->breadcrumbs = array(
  '服务支持' => '/c/service',
  '建议留言',
 );
 $C->pageTitle = "建议留言";
 $C->description = "销售渠道。";
 $C->keywords = "建议留言";
 $C->addCssFile('http://www.baidu.com/css/ui.common.min.css');
 $C->addScriptFile('http://www.baidu.com/js/xm.base.min.js');
*PDO的封装,curl的封装等




===GET & POST===
*Yaf_Request_Abstract::getParam
 本方法在controller中可以使用$this->getRequest()->getParam($name, $defaultValue)方式调用。
请注意:不要试图用此方法取get和post里的参数,因为此方法取出的值都是由路由而产生的键值对。
比如:/site/index/id/aaa?name=bbb
$this->getRequest()->getParam(“id”)可以正确取到值,但是$this->getRequest()->getParam("name")并不一定能取到(默认路由情况下).
如果需要,请使用下面两个方法。


*Yaf_Request_Http::getQuery()
 本方法在controller中可以使用$this->getRequest()->getQuery($name, $defaultValue)方式调用。
注意:这个方法取的是get形式的参数,并且该值是只读的,也就是即使修改了$_GET对应的值,它也不会改变。因此,使用时,请进行必要的参数处理。


*Yaf_Request_Http::getPost()
 本方法在controller中可以使用$this->getRequest()->getPost($name, $defaultValue)方式调用。
注意:这个方法取的是post的参数。同上,该值是只读的.


;在sdk版本中,对三个方法进行了封装,调用的时候直接使用$controller->getParam/getQuery/getPost即可,对数据都做了转义检查。如下:
 
  
//Base_Ctrl所有controller的父类
class Base_Ctrl extends Yaf_Controller_Abstract {
.....
    public function getParam($name, $defaultValue=null) {
        $value = (null === $defaultValue) ? $this->getRequest()->getParam($name) : $this->getRequest()->getParam($name, $defaultValue);
        return !empty($value) ? addslashes($value) : $value;
    }


    public function getPost($name, $defaultValue=null) {
        $value = (null === $defaultValue) ? $this->getRequest()->getPost($name) : $this->getRequest()->getPost($name, $defaultValue);
        return !empty($value) ? Common::daddslashes($value) : $value;
    }
    
    public function getQuery($name, $defaultValue=null) {
        $value = (null === $defaultValue) ? $this->getRequest()->getQuery($name) : $this->getRequest()->getQuery($name, $defaultValue);
        return !empty($value) ? Common::daddslashes($value) : $value;
    }
.....
}





===错误与异常机制===
*关注如下两个配置
 
  
application.dispatcher.throwException=TRUE
application.dispatcher.catchException=TRUE

;手册中描述:
Yaf实现了一套错误和异常捕获机制, 主要是对常见的错误处理和异常捕获方法做了一个简单抽象, 方便应用组织自己的错误统一处理逻辑.
Yaf自身出错时候, 根据配置可以分别采用抛异常或者触发错误的方式来通知错误. 
在appliation.dispatcher.throwException(配置文件, 或者通过Yaf_Dispatcher::throwException(true))打开的情况下, Yaf会抛异常, 否则则会触发错误.
在application.dispatcher.catchException(配置文件, 或者可通过Yaf_Dispatcher::catchException(true))开启的情况下, 当Yaf遇到未捕获异常的时候, 就会把运行权限, 交给当前模块的Error Controller的Error Action动作, 而异常或作为请求的一个参数, 传递给ErrorAction.
在Error Action中可以通过$request->getRequest()->getParam("exception")获取当前发生的异常.


在程序中,我们需要自己捕捉并且必须适当的显示错误。所以我们两个配置均为TRUE


*sdk版本ErrorController的实现
 
  
class ErrorController extends Base_Ctrl {


    public function errorAction($exception) {
        $exceptionType = get_class($exception);
        $this->getView()->assign("error", $exception);
        $this->getView()->assign("exceptionType", $exceptionType);
        $this->render('error');
    }


}



*sdk版本errorAction的模板
 
  
//当定义了IN_DEBUG表示的是开发测试环境,显示相关错误信息
if ( defined('IN_DEBUG') && IN_DEBUG ) { ?>

   

Debug Mode:


   

Msg : getMessage();?>


   

File: getFile();?>


   

Line: getLine();?>


   

Code: getCode();?>




//标准错误异常处理情况
//Exception是标准的开发抛出的错误,可以信任并且直接显示

getMessage();?>


//这两个是属于没有找到controller或者action的情况,可以以404来处理

您訪問的地址不存在



//其他情况

系統繁忙,請稍候再試






==思维导图==




[[文件:YAF.png]]
==参考资料==
;[http://www.php.net/manual/en/book.yaf.php Yaf官方文档]
;[http://www.laruence.com/2012/07/06/2649.html Yaf的一些资源]

你可能感兴趣的:(PHP相关)