yaf 基礎(chǔ)

快速開始

典型的目錄結(jié)構(gòu)

+ public
  |- index.php //入口文件
  |- .htaccess //重寫規(guī)則    
  |+ css
  |+ img
  |+ js
+ conf
  |- application.ini //配置文件   
+ application
  |+ controllers
     |- Index.php //默認(rèn)控制器
  |+ views    
     |+ index   //控制器
        |- index.phtml //默認(rèn)視圖
  |+ modules //其他模塊
  |+ library //本地類庫(kù)
  |+ models  //model目錄
  |+ plugins //插件目錄

入口文件

所有請(qǐng)求的入口, 一般都借助于rewrite規(guī)則, 把所有的請(qǐng)求都重定向到這個(gè)入口文件.

經(jīng)典的入口文件public/index.php

<?php
define("APP_PATH",  realpath(dirname(__FILE__) . '/../')); /* 指向public的上一級(jí) */
$app  = new Yaf_Application(APP_PATH . "/conf/application.ini");
$app->run();

重寫規(guī)則

Apache的Rewrite (httpd.conf)

#.htaccess, 當(dāng)然也可以寫在httpd.conf
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* index.php

Nginx的Rewrite (nginx.conf)

server {
  listen ****;
  server_name  domain.com;
  root   document_root;
  index  index.php index.html index.htm;

  if (!-e $request_filename) {
    rewrite ^/(.*)  /index.php/$1 last;
  }
}

配置文件

  • 配置文件支持繼承, 支持分節(jié). 并對(duì)PHP的常量進(jìn)行支持.
  • 在第一個(gè)運(yùn)行的時(shí)候載入配置文件, 把格式化后的內(nèi)容保持在內(nèi)存中. 直到配置文件有了修改, 才會(huì)再次載入.

控制器

  • 默認(rèn)的模塊/控制器/動(dòng)作, 都是以Index命名的, 這是可通過配置文件修改的.
  • 對(duì)于默認(rèn)模塊, 控制器的目錄是在application目錄下的controllers目錄下, Action的命名規(guī)則是"名字+Action"

默認(rèn)控制器application/controllers/Index.php

<?php
class IndexController extends Yaf_Controller_Abstract {
   public function indexAction() {//默認(rèn)Action
       $this->getView()->assign("content", "Hello World");
   }
}
?>

視圖文件

  • Yaf支持簡(jiǎn)單的視圖引擎, 并且支持用戶自定義自己的視圖引擎, 比如Smarty.
  • 對(duì)于默認(rèn)模塊, 視圖文件的路徑是在application目錄下的views目錄中以小寫的action名的目錄中.

默認(rèn)Action的視圖application/views/index/index.phtml

<html>
 <head>
   <title>Hello World</title>
 </head>
 <body>
  <?php echo $content;?>
 </body>
</html>

使用代碼生成工具

Yaf提供了代碼生成工具

github地址

代碼生成工具的使用

php yaf_cg newapp #newapp 是生成的目錄名

將得到的newapp 目錄, 拷貝到Webserver的documentRoot目錄下


配置文件

php.ini 配置項(xiàng)

php.ini

[yaf]
# 必要配置O茸稀!可以在項(xiàng)目中動(dòng)態(tài)動(dòng)態(tài)調(diào)整想许,來(lái)適應(yīng)不同的生產(chǎn)環(huán)境
yaf.environ = product 
yaf.library = NULL
yaf.cache_config = 0
yaf.name_suffix = 1
yaf.name_separator = ""
yaf.forward_limit = 5
yaf.use_namespace = 0
yaf.use_spl_autoload = 0

配置解釋:

  • yaf.environ 環(huán)境名稱, 當(dāng)用INI作為Yaf的配置文件時(shí), 這個(gè)指明了Yaf將要在INI配置中讀取的節(jié)的名字

  • yaf.library 全局類庫(kù)的目錄路徑

  • yaf.cache_config 是否緩存配置文件(只針對(duì)INI配置文件生效), 打開此選項(xiàng)可在復(fù)雜配置的情況下提高性能

  • yaf.name_suffix 在處理Controller, Action, Plugin, Model的時(shí)候, 類名中關(guān)鍵信息是否是后綴式, 比如UserModel, 而在前綴模式下則是ModelUser

  • yaf.name_separator 在處理Controller, Action, Plugin, Model的時(shí)候, 前綴和名字之間的分隔符, 默認(rèn)為空, 也就是UserPlugin, 加入設(shè)置為"_", 則判斷的依據(jù)就會(huì)變成:"User_Plugin", 這個(gè)主要是為了兼容ST已有的命名規(guī)范

  • yaf.forward_limit forward最大嵌套深度

  • yaf.use_namespace 開啟的情況下, Yaf將會(huì)使用命名空間方式注冊(cè)自己的類, 比如Yaf_Application將會(huì)變成Yaf\Application

  • yaf.use_spl_autoload 開啟的情況下, Yaf在加載不成功的情況下, 會(huì)繼續(xù)讓PHP的自動(dòng)加載函數(shù)加載, 從性能考慮, 除非特殊情況, 否則保持這個(gè)選項(xiàng)關(guān)閉

application.ini配置項(xiàng)

  • Yaf_Application初始化時(shí)刻需要給出的必要配置
  • Yaf通過在不同的環(huán)境中, 選取不同的配置節(jié), 再結(jié)合配置可繼承, 來(lái)實(shí)現(xiàn)一套配置適應(yīng)多種環(huán)境(線上,測(cè)試,開發(fā)).

必要配置

application.director 應(yīng)用的絕對(duì)目錄路徑

可選的配置

| 名稱 | 值類型 | 默認(rèn)值 | 說明 |
| :-------- |: --------| :------- |:------- |
| application.ext | String | php | PHP腳本的擴(kuò)展名 |
| application.bootstrap | String | Bootstrapplication.php | Bootstrap路徑(絕對(duì)路徑) |
| application.library | String | application.directory + "/library" | 本地(自身)類庫(kù)的絕對(duì)目錄地址 |
| application.baseUri | String | NULL | 在路由中, 需要忽略的路徑前綴, 一般不需要設(shè)置, Yaf會(huì)自動(dòng)判斷. |
| application.dispatcher.defaultModule | String | index | 默認(rèn)的模塊 |
| application.dispatcher.throwException | Bool | True | 在出錯(cuò)的時(shí)候, 是否拋出異常 |
| application.dispatcher.catchException | Bool | False | 是否使用默認(rèn)的異常捕獲Controller, 如果開啟, 在有未捕獲的異常的時(shí)候, 控制權(quán)會(huì)交給ErrorController的errorAction方法, 可以通過$request->getException()獲得此異常對(duì)象 |
| application.dispatcher.defaultController | String | index | 默認(rèn)的控制器 |
| application.dispatcher.defaultAction | String | index | 默認(rèn)的動(dòng)作 |
| application.view.ext | String | phtml | 視圖模板擴(kuò)展名 |
| application.modules | String | Index | 聲明存在的模塊名, 請(qǐng)注意, 如果你要定義這個(gè)值, 一定要定義Index Module |
| application.system.* | String | * | 通過這個(gè)屬性, 可以修改yaf的runtime configure, 比如application.system.lowcase_path, 但是請(qǐng)注意只有PHP_INI_ALL的配置項(xiàng)才可以在這里被修改, 此選項(xiàng)從2.2.0開始引入 |

獲取自定義配置文件:

//獲取所有配置
print_r(Yaf_Application::app()->getConfig());
//獲取單個(gè)配置
print_r(Yaf_Application::app()->getConfig()->redis);

自動(dòng)加載器

Yaf在自啟動(dòng)的時(shí)候, 會(huì)通過SPL注冊(cè)一個(gè)自己的Autoloader, 出于性能的考慮, 對(duì)于框架相關(guān)的MVC類, Yaf Autoloader只以目錄映射的方式嘗試一次.

目錄映射規(guī)則:

| 類型 | 后綴(或者前綴, 可以通過php.ini中ap.name_suffix來(lái)切換) | 映射路徑 |
| :-------- |: --------| :------- |
| 控制器 | Controller | 默認(rèn)模塊下為{項(xiàng)目路徑}/controllers/, 否則為{項(xiàng)目路徑}/modules/{模塊名}/controllers/ |
| 數(shù)據(jù)模型 | Model | {項(xiàng)目路徑}/models/ |
| 插件 | Plugin | {項(xiàng)目路徑}/plugins/ |

全局類和自身類(本地類)

Yaf為了方便在一臺(tái)服務(wù)器上部署的不同產(chǎn)品之間共享公司級(jí)別的共享庫(kù), 支持全局類和本地類兩種加載方式.

  • 全局類是指, 所有產(chǎn)品之間共享的類, 這些類庫(kù)的路徑是通過yaf.library在php.ini
  • 本地類是指, 產(chǎn)品自身的類庫(kù)

類的加載規(guī)則

Yaf規(guī)定類名中必須包含路徑信息, 也就是以下劃線"_"分割的目錄信息. Yaf將依照類名中的目錄信息, 完成自動(dòng)加載:

全局類:

一個(gè)映射的例子Zend_Dummy_Foo

 //Yaf將在如下路徑尋找類Foo_Dummy_Bar
 {類庫(kù)路徑(php.ini中指定的yaf.library)}/Foo/Dummy/Bar.php

本地類:

  //申明, 凡是以Foo和Local開頭的類, 都是本地類
 $loader = Yaf_Loader::getIgnstance();
 $loader->registerLocalNamespace(array("Foo", "Local"));
 //Yaf將在如下路徑尋找類Foo_Dummy_Bar
 {類庫(kù)路徑(conf/application.ini中指定的yaf.library)}/Foo/Dummy/Bar.php

手動(dòng)導(dǎo)入文件:

Yaf_Loader::import('conf/NetWorkCode.php');
echo NetWorkCode::NETWORK_ERROR;

Bootstrap

簡(jiǎn)介

Bootstrap, 也叫做引導(dǎo)程序. 它是Yaf提供的一個(gè)全局配置的入口, 在Bootstrap中, 你可以做很多全局自定義的工作.

使用Bootstrap

在一個(gè)Yaf_Application被實(shí)例化之后, 運(yùn)行(Yaf_Application::run)之前, 可選的我們可以運(yùn)行Yaf_Application::bootstrap

<?php
$app = new Yaf_Application("conf.ini");
$app
 ->bootstrap() //可選的調(diào)用
 ->run();
}

當(dāng)bootstrap被調(diào)用的時(shí)刻, Yaf_Application就會(huì)默認(rèn)的在APPLICATION_PATH下, 尋找Bootstrap.php, 而這個(gè)文件中, 必須定義一個(gè)Bootstrap類, 而這個(gè)類也必須繼承自Yaf_Bootstrap_Abstract.

實(shí)例化成功之后, 所有在Bootstrap類中定義的, 以_init開頭的方法, 都會(huì)被依次調(diào)用, 而這些方法都可以接受一個(gè)Yaf_Dispatcher實(shí)例作為參數(shù).

<?php

/**
 * 所有在Bootstrap類中, 以_init開頭的方法, 都會(huì)被Yaf調(diào)用,
 * 這些方法, 都接受一個(gè)參數(shù):Yaf_Dispatcher $dispatcher
 * 調(diào)用的次序, 和申明的次序相同
 */
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");
        }
}

插件

簡(jiǎn)介

Yaf支持用戶定義插件來(lái)擴(kuò)展Yaf的功能. 它們都必須繼承自Yaf_Plugin_Abstract. 插件要發(fā)揮功效, 也必須現(xiàn)實(shí)的在Yaf中進(jìn)行注冊(cè), 然后在適當(dāng)?shù)膶?shí)際, Yaf就會(huì)調(diào)用它.

Yaf支持的Hook

| 觸發(fā)順序 | 名稱 | 觸發(fā)時(shí)機(jī) | 說明 |
| :-------- |: --------| :------- |:------- |
| 1 | routerStartup | 在路由之前觸發(fā) | 這個(gè)是7個(gè)事件中, 最早的一個(gè). 但是一些全局自定的工作, 還是應(yīng)該放在Bootstrap中去完成 |
| 2 | routerShutdown | 路由結(jié)束之后觸發(fā) | 此時(shí)路由一定正確完成, 否則這個(gè)事件不會(huì)觸發(fā) |
| 3 | dispatchLoopStartup | 分發(fā)循環(huán)開始之前被觸發(fā) |
| 4 | preDispatch | 分發(fā)之前觸發(fā) | 如果在一個(gè)請(qǐng)求處理過程中, 發(fā)生了forward, 則這個(gè)事件會(huì)被觸發(fā)多次 |
| 5 | postDispatch | 分發(fā)結(jié)束之后觸發(fā) | 此時(shí)動(dòng)作已經(jīng)執(zhí)行結(jié)束, 視圖也已經(jīng)渲染完成. 和preDispatch類似, 此事件也可能觸發(fā)多次 |
| 6 | dispatchLoopShutdown | 分發(fā)循環(huán)結(jié)束之后觸發(fā) | 此時(shí)表示所有的業(yè)務(wù)邏輯都已經(jīng)運(yùn)行完成, 但是響應(yīng)還沒有發(fā)送 |

定義插件

  • 繼承自Yaf_Plugin_Abstract
  • 需要在插件類中定義和上面事件同名的方法
  • 方法就會(huì)在該事件觸發(fā)的時(shí)候被調(diào)用
  • 插件方法, 可以接受倆個(gè)參數(shù), Yaf_Request_Abstract實(shí)例和Yaf_Response_Abstract實(shí)例
    <?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) {
        }
    }

注冊(cè)插件

Yaf_Dispatcher注冊(cè)插件, 一般的插件注冊(cè)都會(huì)放在Bootstrap中進(jìn)行

<?php
class Bootstrap extends Yaf_Bootstrap_Abstract{

        public function _initPlugin(Yaf_Dispatcher $dispatcher) {
            $user = new UserPlugin();
            $dispatcher->registerPlugin($user);
        }
}

插件目錄

放置在APPLICATION_PATH下的plugins目錄, 這樣在自動(dòng)加載的時(shí)候, 加載器通過類名, 發(fā)現(xiàn)這是個(gè)插件類

路由和路由協(xié)議

概述

路由器主要負(fù)責(zé)解析一個(gè)請(qǐng)求并且決定什么module剥汤、controller、action被請(qǐng)求;它同時(shí)也定義了一種方法來(lái)實(shí)現(xiàn)用戶自定義路由骚秦,這也使得它成為最重要的一個(gè)MVC組組件.

路由組件有兩個(gè)部分:路由器(Yaf_Router)和路由協(xié)議(Yaf_Route_Abstract).

默認(rèn)情況下,我們的路由器是Yaf_Router, 而默認(rèn)使用的路由協(xié)議是Yaf_Route_Static,是基于HTTP路由的

路由類別

Yaf_Route_Simple
Yaf_Route_Supervar
Yaf_Route_Static
Yaf_Route_Map
Yaf_Route_Rewrite
Yaf_Route_Regex

默認(rèn)路由協(xié)議

默認(rèn)的路由協(xié)議Yaf_Route_Static, 就是分析請(qǐng)求中的request_uri, 在去除掉base_uri以后, 獲取到真正的負(fù)載路由信息的request_uri片段, 具體的策略是, 根據(jù)"/"對(duì)request_uri分段, 依次得到Module,Controller,Action, 在得到Module以后, 還需要根據(jù)Yaf_Application::$modules來(lái)判斷Module是否是合法的Module, 如果不是, 則認(rèn)為Module并沒有體現(xiàn)在request_uri中, 而把原Module當(dāng)做Controller, 原Controller當(dāng)做Action:

工作中默認(rèn)的即可滿足需求她倘,如果有需要可以自己定制

具體參考:http://www.laruence.com/manual/yaf.routes.html

簡(jiǎn)單路由

/*
    * http://yaf.test.com/?m=order&c=orderinfo&a=show
    */
    //        $router=$dispatcher->getRouter();
    //        $route = new Yaf_Route_Simple("m", "c", "a");
    //        $router->addRoute("name", $route);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末璧微,一起剝皮案震驚了整個(gè)濱河市作箍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌前硫,老刑警劉巖胞得,帶你破解...
    沈念sama閱讀 212,542評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異屹电,居然都是意外死亡阶剑,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門危号,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)牧愁,“玉大人,你說我怎么就攤上這事外莲≈戆耄” “怎么了?”我有些...
    開封第一講書人閱讀 158,021評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵偷线,是天一觀的道長(zhǎng)磨确。 經(jīng)常有香客問我,道長(zhǎng)声邦,這世上最難降的妖魔是什么乏奥? 我笑而不...
    開封第一講書人閱讀 56,682評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮亥曹,結(jié)果婚禮上邓了,老公的妹妹穿的比我還像新娘。我一直安慰自己媳瞪,他們只是感情好骗炉,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,792評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著材失,像睡著了一般痕鳍。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上龙巨,一...
    開封第一講書人閱讀 49,985評(píng)論 1 291
  • 那天笼呆,我揣著相機(jī)與錄音,去河邊找鬼旨别。 笑死诗赌,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的秸弛。 我是一名探鬼主播铭若,決...
    沈念sama閱讀 39,107評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼洪碳,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了叼屠?” 一聲冷哼從身側(cè)響起瞳腌,我...
    開封第一講書人閱讀 37,845評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎镜雨,沒想到半個(gè)月后嫂侍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,299評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡荚坞,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,612評(píng)論 2 327
  • 正文 我和宋清朗相戀三年挑宠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片颓影。...
    茶點(diǎn)故事閱讀 38,747評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡各淀,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出诡挂,到底是詐尸還是另有隱情碎浇,我是刑警寧澤,帶...
    沈念sama閱讀 34,441評(píng)論 4 333
  • 正文 年R本政府宣布咆畏,位于F島的核電站南捂,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏旧找。R本人自食惡果不足惜溺健,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,072評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望钮蛛。 院中可真熱鬧鞭缭,春花似錦、人聲如沸魏颓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)甸饱。三九已至沦童,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間叹话,已是汗流浹背偷遗。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留驼壶,地道東北人氏豌。 一個(gè)月前我還...
    沈念sama閱讀 46,545評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像热凹,于是被迫代替她去往敵國(guó)和親泵喘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子泪电,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,658評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)纪铺,斷路器相速,智...
    卡卡羅2017閱讀 134,637評(píng)論 18 139
  • 介紹 Yaf框架是一個(gè)c語(yǔ)言編寫的PHP框架,是一個(gè)以PHP擴(kuò)展形式提供的PHP開發(fā)框架霹陡,相比于一般的PHP框架和蚪,...
    簡(jiǎn)單方式閱讀 18,664評(píng)論 1 44
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,849評(píng)論 25 707
  • 螞蟻冬眠的季節(jié) 你的思念像一片片落葉 風(fēng)將你的愛吹去千里之外 南方的冬天更加濕冷 請(qǐng)你多添些衣裳 多日不見 是否還...
    Derek_Kun閱讀 851評(píng)論 1 5
  • 林俊杰-曹操 在中國(guó)我們從小就被反復(fù)地告知“第一印象很重要”。因此烹棉,我們?cè)诤退说谝淮我娒鏁r(shí),必然得好好地收拾打扮...
    一縷魚魂閱讀 339評(píng)論 0 1