一、框架課程總結
框架、設計模式和隊列是5月份公開課的三個主題,第一周講設計模式,第二、四周講框架,第三周講隊列。框架講了兩周,介紹了框架的概念、PHP框架的應用范圍,以及常用的PHP框架,今天是框架的最后一講,是對整個框架系列課程的匯總,同時和大家討論一些框架之外、或者框架之下的技術。
今天要討論的分為這幾個方面,總結框架系列課程、探討框架可能存在,或者解決不了的問題,以及其解決方案和當前的探索。
在框架第一講中,志華老師也站得高度很高,講述了框架、架構的概念,以及對比了它的異同。總結來講就是架構涉及到的是一個產品的性能、可擴展性之類問題。而框架則涉及到一個產品在實際的實現過程之中,所用的技術方案。比如性能和可擴展性,也就是架構所關系的內容,和底層語言其實關系不大。無論是PHP語言,還是Ruby語言,來實現一個大型網站,后端都可以部署數據庫,數據庫有主從,都需要緩存,緩存都可以是Memcached,數據庫可以是MySQL。而框架則是我們做一個產品實現所用的具體技術實現方案,不但跟語言本身關系密切,而且涉及到在開發中的具體開發方案。打一個比喻,建造一個開發區。架構就是圖紙,水、電、暖布局、樓盤、商業布局、容量布局,而框架則是細化的實施方案,這個寫字樓是板樓還是塔樓,是做寫字樓還是做酒店,前者與材料外觀無關,后者則與材料外觀相關。
再在后面的課程中,我們分別了解了Durpal、Symfony、ThinkPHP、YII、ZendFramework等框架的用法與擴展。
通過對框架的學習,我們認識到各自的框架都有自己的優勢,使用框架帶來了巨大的便利,比如很快構建起一個腳手架,英文叫Skeleton,有很多可用的方便工具和函數。當然,學習一套框架有成本,使用一套框架更有約束。也能看到框架的作用,可以歸結為如下幾點:
1、快速構建的腳手架,而不是從零開始
2、一套共同的約束和規則,保證開發質量。
3、工具和函數庫、共同認識,無疑提高了開發效率
二、跳出PHP應用開發框架看框架
但是?今天我們從兩個層次來看討論問題。
第一個層次是高級的層次,我們簡單看一下。在前面講的,都基於PHP的應用開發框架而展開,即使我們講了這么些框架,但這些框架也只是小部分代表,如果只站在應用的這個層次再多討論也沒有太大的意義。我們要跳出來看,就像,框架就是在應用開發這個層次嗎?就只討論PHP語言嗎?他們的共同特點在哪里?
框架並不是局限於某個特定語言、或者特定用途東西。比如我們講Web 開發框架,這個Web開發框架,可以是PHP的,也可以是Ruby語言寫的,像Rubyon rails,甚至最近流近的 go 語言,也開始有自己的Web開發框架,甚至還有用 C語言去寫的。而框架也不僅限於Web開發或者網站功能開發,有測試框架,像PhpUnit,JUnit這樣的軟件。像Thrift、ICE這樣的,屬於分布式通信框架。
共同特點,有幾點:
1、都提供了自己領域內較完整強大的功能。(區別於函數庫,比函數庫更綜合,更完整)。
2、都提供了自己領域內功能較具體的實現。(區別於架構這個較虛的概念)。
3、但是提供的是一些規范、腳手架。(區別於現成的產品,這只是一個特定領域的半成品)。
三、框架可能或者帶來的問題
了解了框架在整個編程開發領域,大面上的感性認識,我們具體來探討這兩周公開課下來,框架所不能解決的問題。這是第二個層次,是更深入的層次。
1、第一個問題,就是開發習慣上的問題。如果團隊決定采用一個框架。特別是全新的框架,就比較費勁了,可能還得有一個正式的培訓階段。
2、第二個問題,框架都有其適用的場景,需要架構師需要在什么階段在合適的時候,采用合適的框架。
3、第三個問題,性能問題。大部分的框架,都用到了一些復雜的規則,比如ORM、比如模板引擎,這些東西,天生就是比較低效,尤其是像PHP這樣的動態腳本語言。在企業系統、小流量的時候,還好,但是如果進入大流量時期,這個性能問題,就不容忽視了。
4、第四個問題,是擴展性問題。比如流量大了,數據庫后端,也不再是一個數據庫了,同一個數據類型也不再是一個數據表了。這個時候,框架有些地方,就該動動了。ThinkPHP那一講上分享了這樣的問題。
四、PHP性能的改進手段
好的,那我們來看一下,PHP業界,在提高框架性能、或者者整個PHP性能問題上,所做的一些探索。這也是我們今天的重點。
那么,我們想一想,你想提高PHP程序的效率,可以做哪些嘗試?另外還有一個意思的事情是,你覺得,誰對提高 PHP程序的效率,最有動力?
第一、我們知道,PHP很容易寫出很低效的程序,數據庫頻繁重連。寫的查詢很低效。某個函數實現,可能有問題等等。那么這些問題,需要有一個很好的手段去發現。這個時候,一個神器誕生了。這就是XHProf。XHProf是誰出的呢?Facebook,這是我們剛才講的誰最有動力來提高PHP效率呢,誰在大規模的環境下,經常使用PHP,就最有動力。Facebook就最有這個動力了。
第二、上面講的是第一個層次,先把PHP語言本身的一些東西給優化了。把第一個層次應用到框架上,就是我們通過XHprof可能發現了框架的一些性能瓶頸。第二個層次呢?我們再反問一下,提高程序性能最有效的方式是什么?我相信大部分同學都會提一個手段,緩存。沒有錯,第二個提升的層次就是緩存,我們將模板編譯,是一種緩存方式,或者在庫中,支持一些外部緩存,比如ThinkPHP 就是一個很典型的例子,支持模板編譯緩存。也支持大量預置的Cache函數庫。
第三個層次,有人就想了,PHP這種動態的腳本語言,在每一次運行時都是現編譯解析,有沒有一些辦法,把這個每次編譯解析的過程省了。這其實也經過了兩個步驟。在CGI時代,每一個PHP頁面的運行,所有的PHP模塊都需要重新加載。每一個程序都有這個加載過程其實很浪費的。
因此就進入了mod_php 這個階段,就是這張圖
而再到后來改進成這張圖,
再到后來,人們從PHP本身的編譯過程上再省一步,加進了opcache,就是opcode 的cache,就是從PHP腳本編譯成為操作碼的緩存,這樣的話,對程序,省去了第一個編譯環節。
就成了這一張圖
上面虛線的部分,就是緩存住了的,一個腳本只執行一次編譯,后面的調用,都共享第一次編譯所留下來的opcode緩存,APC就是一個實現opcode緩存的框架,同類的還有XCache,eAccelerator,我們今天的例子是用的zend opcache。
上面說了這么多,這還只是第三個層次,其實還有三個層次的手段。
第四個層次,是將核心的,有瓶頸的業務邏輯,轉到后端去實現。也就是說不用PHP了,舉一個典型的例子,就是分庫分表,連接池這樣的功能,當然,分庫分表,我們可以采用PHP來實現,但是連接池這樣的功能就比較費勁一些了。所以一般對於一個高效的分布式架構來講,這種邏輯會有一個DB Proxy,來管理着客戶端對服務器的長連接,PHP本身不再直接連接數據庫,而是連接這個代理,由這個代理,來實現多表查詢等操作。這里只是舉一個例子。比如我們講的緩存,甚至KVDB、全文檢索,估計也有朋友寫過PHP版存儲和引擎,但是實際上在現實的使用中,還是更多的使用后端的服務。
第五個層次,就是一些大神出來了,他們受不了傳統PHP,PHP框架的低效,開發模塊,開發模塊化的PHP框架。這個比較好理解。模塊嘛,C語言實現,編譯成二進制共享庫,從Web Server一啟動就預加載。所以必然會高效一截。今天我們來看看Yaf、Phalcon這兩C寫的框架。也正好呼應咱們框架總結的這個主題。
第六個層次,我就該來問了?是不是PHP本身也是非常陳舊和低效了,是不是有改進的空間,甚至PHP重新用不一樣的思路實現,可行不可行?這個問題,后面慢慢道來。
好的,是不是感覺有了一種全新的視角?我們回過來看看這些改進,在實際生產中的實現。
五、PHP性能改進在生產中的實踐
5.1、XHProf
首先來看一下XHProf這個工具,怎么能改進我們的PHP語言本身。
首先安裝這個工具,就是模塊化安裝。
我們封裝一下操作類。
<?php /** * 優才網公開課示例代碼 * * XHProf 封裝類 * * @author 伍星 * @see http://www.ucai.cn */ class XHProf { public function __construct() { // start profiling $XHPROF_ROOT = "/home/wwwroot/ucai_app/samples"; include_once $XHPROF_ROOT . "/xhprof_lib/utils/xhprof_lib.php"; include_once $XHPROF_ROOT . "/xhprof_lib/utils/xhprof_runs.php"; } public function beginProf() { xhprof_enable(); register_shutdown_function('XHProf::endProf'); } public function endProf() { $xhprof_data = xhprof_disable(); $xhprof_runs = new XHProfRuns_Default(); $run_id = $xhprof_runs->save_run($xhprof_data, "xhprof_foo"); echo "<a href=\"http://samples.app.ucai.cn/xhprof_html/index.php?run=$run_id&source=xhprof_foo\">性能分析結果</a>"; } }
值得注意的是這句話:
register_shutdown_function('XHProf::endProf');
什么意思呢,就是在整個頁面完成了之后,輸出結果報表鏈接。
5.2 、Opcache的安裝與配置
其次我們來看看 opcache,安裝過程沒有什么講的,主要是推薦一個配置,並且需要強調,opcache不是PHP extension,是zend extension, 所以非常容易出錯。配置如下:
[opcache] zend_extension="/usr/local/php/lib/php/extensions/no-debug-zts-20090626/opcache.so" opcache.enable_cli=1 opcache.memory_consumption=128 //共享內存大小, 這個根據你們的需求可調 opcache.interned_strings_buffer=8 //interned string的內存大小, 也可調 opcache.max_accelerated_files=4000 //最大緩存的文件數目 opcache.revalidate_freq=60 //60s檢查一次文件更新 opcache.fast_shutdown=1 //打開快速關閉, 打開這個在PHP Request Shutdown的時候 // 會收內存的速度會提高 opcache.save_comments=0 //不保存文件/函數的注釋
5.3、Yaf和Phalcon
再次來看兩個C語言寫的PHP框架
第一個介紹的是Yaf 框架,這是一個純C語言框架。具體的安裝過程和實驗如下:
1、從github 下載 php-yaf https://github.com/laruence/php-yaf
2、解壓,按PHP模塊的編譯手法編譯
phpize ./configure --with-php- /usr/local/php/bin/php-config make make install
3、在php.ini 中配置
extension = "yaf.so" yaf.environ="product"
4、通過命令行上執行 php –m|grep yaf 你就能看到模塊已經安裝好了。
5、余下的就是Web測試。
在源碼目錄下,找到
php-yaf-master/tools/cg ./yaf_cg ucai_gkk
6、將output 目錄下的 ucai_gkk 移至 samples.app.ucai.cn 所在的目錄下,就可以通過 http://samples.app.ucai.cn/ucai_gkk
來訪問。
7、我們可以做一下改造實驗,了解一下這個框架的基本結構。
大家可以看到,我只是一通過一個工具,就生成了整個程序的框架,就可以根據需要,添加自己的業務邏輯。
比如 ,在models/Sample.php 中增加一個方法,
public function selectProductSample() { return "<h1>Hello Haha</h1>"; }
在 views 目錄下新建文件,product/index.phtml
<?php /** * 優才網公開課示例代碼 * * Yaf 視圖 * * @author 伍星 * @see http://www.ucai.cn */ echo $content, " I am ", $name, " From Product"; ?>
在controllers 目錄下建立 Product.php
<?php /** * 優才網公開課示例代碼 * * Yaf 控制器 * * @author 伍星 * @see http://www.ucai.cn */ /** * @name IndexController * @author root * @desc 默認控制器 * @see http://www.php.net/manual/en/class.yaf-controller-abstract.php */ class ProductController extends Yaf_Controller_Abstract { /** * 默認動作 * Yaf支持直接把Yaf_Request_Abstract::getParam()得到的同名參數作為Action的形參 * 對於如下的例子, 當訪問http://yourhost/hello/index/index/index/name/root 的時候, 你就會發現不同 */ public function indexAction($name = "Product") { //1. fetch query $get = $this->getRequest()->getQuery("get", "default value"); //2. fetch model $model = new SampleModel(); //3. assign $this->getView()->assign("content", $model->selectProductSample()); $this->getView()->assign("name", $name); //4. render by Yaf, 如果這里返回FALSE, Yaf將不會調用自動視圖引擎Render模板 return TRUE; } }
這樣我們就可以通過,http://samples.app.ucai.cn/hello/?a=index&c=product
這樣的鏈接來訪問,我們新建的內容了。操作起來很簡單。
用同樣的方式,我們安裝Phalcon。雖然從形式上,它更簡單。通過目錄就知道,內容更為豐富。
這也是Yaf跟Phalcon的很大的不同之處,Yaf盡管效率很高,但是要在生產上使用,還是略顯單薄,功能不夠豐富。而Phalcon則真的是功能很全的。正像優才網培養的叫全棧工程師,而Phalcon也號稱自己是Full Stack 的一個框架。
這次,沒有工具來生成一個基本的框架,但是我們可以從Github上的一個教程,作為切入點。
https://github.com/phalcon/tutorial
下載了這個教程之后,我們就可以開始動手了。先看看功能 。
放到相應的目錄下之后,比如 http://samples.app.ucai.cn 目錄下之后,得配置一下rewrite 規則。
rewrite ^/phalcon/(.*?)$ /phalcon/public/index.php?_url=/$1 last; rewrite ^/phalcon$ /phalcon/public/index.php last;
然后,通過 http://samples.app.ucai.cn/phalcon/ 可以訪問。
發現有一個注冊功能,那我們就來想這個數據怎么保存的。
發現在 public/index.php 中有一段配置,
//Set the database service $di->set('db', function() { return new \Phalcon\Db\Adapter\Pdo\Mysql(array( "host" => "127.0.0.1", "username" => "xxxx", "password" => "xxxxx", "dbname" => "xxxxxx" )); });
我們在這里改了配置了之后,再看看提交的情況。
發現在SignupControll.php 中有一段保存代碼 ,
$user = new Users(); $user->name = $name; $user->email = $email; //Store and check for errors if (($userid = $user->save()) == true) { echo 'Thanks for register!'; } else { echo 'Sorry, the next problems were generated: '; foreach ($user->getMessages() as $message) { echo $message->getMessage(), '<br/>'; } }
過去看這個 models/Users.php 卻是空的?
我們在不修改Users.php的時候,看看是否能將數據保存進去?
當然前提是建一個表,因為我懷疑,這存在某種關系 的映射。
CREATE TABLE `users` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(70) NOT NULL, `email` varchar(70) NOT NULL, PRIMARY KEY (`id`) );
發現果不其然,保存進去了,好,我們再進一步,找一現實中可能會用的表格格式,比如下划線的表格 users_exinfo。
CREATE TABLE `users_exinfo` ( `id` int(10) unsigned NOT NULL default 0, `schoolname` varchar(70) NOT NULL, `age` int NOT NULL, PRIMARY KEY (`id`) );
看看能否實現保存,於是乎也建了一個空類。
class UsersExinfo extends Phalcon\Mvc\Model{ }
同時也修改了視圖,將數據保存了進去。
結果如下:
大家看到,成功地保存了數據。
5.4、zephir高效開發模塊
好的,講到這里,衍生出一個小話題,就是開發模塊。
在PHP里,開發模塊,是一個很痛苦的過程。因為C語言,大家都知道,是出了名的難學的,值得高興的是,也是Phalcon這個團隊的童鞋們,也為我們准備了一個高效的開發模塊的語言,稱之為zephir。正因為擴展如此難以開發,但是擴展又是如此高效,所以我們要用高效的方式來開發擴展。
git clone https://github.com/phalcon/zephir.git cd zephir/ mv zephir /usr/local/
然后就可以開發模塊了,我們使用
zephir init gkk
生成模塊的框架,
然后 cd gkk/gkk
編寫 hello.zep
namespace Gkk; /** * This is a sample class */ class Welcome { /** * This is a sample method */ public function welcome() { echo "你們好!參加優才網公開課的同學們!"; } public function say() { echo "今天是優才網第三十三講公開課了!"; } }
然后再返回
zephir compile
zephir build
然后在 php.ini 中配置
extension=gkk.so
通過 php –m 可以看到相應的模塊。再編寫
test.php <?php $t = new Gkk\Welcome(); $t->say(); echo "\n"; ?>
就能看到相應的輸出。
5.5、各框架性能總結
好的,有關兩個用C開發的框架和相關內容我們就介紹到這里。下面我們來總結一下框架,以及做一些性能評測。
首先來看一下性能評測報告,這是一個專門測框架的github項目出的數據,
博客在這里,
•https://github.com/eryx/php-framework-benchmark
從上面的圖可以看到,兩個用C編寫的框架,性能還是相當可觀的。Yaf比Phalcon性能更強,也不奇怪。因為結構更為簡單,模塊更少。同時也發現,像zend framework這樣的框架,是不能輕易在一個大眾的互聯網產品中使用的,盡管代碼寫得不錯,但是效率太低了,有木有!
5.6、PHP的重寫
在評測之前,大家記起來了沒有,我們上面講了六點,其中有一點是什么?重寫PHP!
那就看看,哪些業界人士,在PHP重寫的路子上做了非常激動人心的嘗試。
剛才講了,誰最有動力?
有兩個方面的人有動力,一個是PHP最大的使用者,一個是PHP官方。最大的使用者,他對PHP的提升,能大幅度地減少資源的占用,一個百分之幾的優化可能就是成百上千台設備的節省。而后者,則要想到如果PHP本身效率提升不上去,在未來的發展過程中,很容易出現轉折,盡管現在還是非常火的。
所有從官方,就有了,PHPng,這個我沒有安裝過,有興趣的同學,可以自己去折騰,https://wiki.php.net/phpng 值得一提的是,咱們國內的鳥哥是這個項目的主要參與者之一。Yaf也是他的作品。而另外一個,則是Facebook主導的,HHVM,其前身是HipHop, 當時的思路是把PHP全部編譯成C++程序,在上線的過程中,上線的是一個二進制包,非常不靈活,修改代碼,需要發包才能生效。如果出現故障,會有災難性的影響。所以演進到現在成了HHVM,全稱是HipHop Virtual Machine。
現在的模式,簡單了講就是可以做為FastCGI 的運行容器。大家安裝過LNMP的同學就知道,在Nginx的后端,也就是說Nginx的配置中,通過
fastcgi_pass 這個配置指向了實際運行PHP的FastCGI 運行容器,PHP自帶的是PHP-FPM(FastCGI Process Manager),而HHVM就是可以一定程度上無縫地替換掉,FPM,比如你kill掉FPM進程,通過
hhvm --mode server -vServer.Type=fastcgi -vServer.Port=9000 &
來啟動HHVM。都不需要修改nginx 配置。就可以訪問了。
但是性能一定程度上,大有提升。
這枚神器有如下特點:
•當然不是小團隊能玩的
•與PHP 5.2引擎+APC相比,可以處理的Web請求吞吐量增加了9倍,而內存消耗減少了5倍。
•如無特殊模塊,可以無縫替換 php-fpm(除了極少數兼容問題)
•1、優點
–FB出品
–強大到令你吃驚,數十倍的性能提升
–已經趨於穩定,無縫替換 PHP-FPM
•2、缺點
–還不是很穩定
–模塊需要遷移
六、各項實踐,性能評測
下面進入性能評測,評測我們相對就比較快速一些。直接用ab命令,來測試上面的所提及的一些改進。
以下評測,所有測試頁面,均為:http://hjvote.app.ucai.cn/index.php 命令行為:
ab -c 20 -n 1000 http://hjvote.app.ucai.cn/index.php
6.1 、冷啟動
1、冷啟動,比如我新啟動的php-fpm,關掉opcache,關掉xhprof
Concurrency Level: 20 Time taken for tests: 4.981 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Total transferred: 478000 bytes HTML transferred: 109000 bytes Requests per second: 200.78 [#/sec] (mean) Time per request: 99.612 [ms] (mean) Time per request: 4.981 [ms] (mean, across all concurrent requests) Transfer rate: 93.72 [Kbytes/sec] received
6.2、第二次
2、第二次,條件同上。
Concurrency Level: 20 Time taken for tests: 4.537 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Total transferred: 478000 bytes HTML transferred: 109000 bytes Requests per second: 220.42 [#/sec] (mean) Time per request: 90.736 [ms] (mean) Time per request: 4.537 [ms] (mean, across all concurrent requests) Transfer rate: 102.89 [Kbytes/sec] received
6.3、打開opcache第一次
Concurrency Level: 20 Time taken for tests: 1.591 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Total transferred: 478000 bytes HTML transferred: 109000 bytes Requests per second: 628.67 [#/sec] (mean) Time per request: 31.813 [ms] (mean) Time per request: 1.591 [ms] (mean, across all concurrent requests) Transfer rate: 293.46 [Kbytes/sec] received
6.4、第二次,條件同上
Concurrency Level: 20 Time taken for tests: 1.254 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Total transferred: 478000 bytes HTML transferred: 109000 bytes Requests per second: 797.70 [#/sec] (mean) Time per request: 25.072 [ms] (mean) Time per request: 1.254 [ms] (mean, across all concurrent requests) Transfer rate: 372.36 [Kbytes/sec] received
6.5、對比再打開xhprof
Concurrency Level: 20 Time taken for tests: 1.254 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Total transferred: 478000 bytes HTML transferred: 109000 bytes Requests per second: 797.44 [#/sec] (mean) Time per request: 25.080 [ms] (mean) Time per request: 1.254 [ms] (mean, across all concurrent requests) Transfer rate: 372.24 [Kbytes/sec] received
6.6、打開XHprof,關掉Opcache
對於這個簡單的頁面,沒有明顯惡化,我們去掉Opcache,打開xhprof
Concurrency Level: 20 Time taken for tests: 12.103 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Total transferred: 595000 bytes HTML transferred: 226000 bytes Requests per second: 82.62 [#/sec] (mean) Time per request: 242.065 [ms] (mean) Time per request: 12.103 [ms] (mean, across all concurrent requests) Transfer rate: 48.01 [Kbytes/sec] received
6.7、第二次、條件同上
Concurrency Level: 20 Time taken for tests: 9.298 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Total transferred: 595000 bytes HTML transferred: 226000 bytes Requests per second: 107.55 [#/sec] (mean) Time per request: 185.952 [ms] (mean) Time per request: 9.298 [ms] (mean, across all concurrent requests) Transfer rate: 62.50 [Kbytes/sec] received
在沒有opcache的情況下,XHProf的加入,導致用戶急劇變慢。
6.8、關掉xhprof HHVM第一次
Concurrency Level: 20 Time taken for tests: 1.142 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Total transferred: 521000 bytes HTML transferred: 109000 bytes Requests per second: 875.84 [#/sec] (mean) Time per request: 22.835 [ms] (mean) Time per request: 1.142 [ms] (mean, across all concurrent requests) Transfer rate: 445.62 [Kbytes/sec] received
6.9、 第二次,條件同上
Concurrency Level: 20 Time taken for tests: 0.852 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Total transferred: 521000 bytes HTML transferred: 109000 bytes Requests per second: 1173.42 [#/sec] (mean) Time per request: 17.044 [ms] (mean) Time per request: 0.852 [ms] (mean, across all concurrent requests) Transfer rate: 597.03 [Kbytes/sec] received
什么感覺?這種數字的差距是不是可以用震撼來形容?通過評測對比,我們對於opcache、hhvm和一般php-fpm性能心里也就有數了。同時也發現,在頁面上開啟XHProf,會導致網頁性能急劇下降,所以不要在生產環境對多人開啟XHProf。或者會帶來非常不好的用戶體驗。
七、自有框架的設計
好的,看完了性能評測,我們來過了一下如果設計一個自有的框架需要哪些元素,或者說需要哪些內容。
1、首先對目錄結構進行一個划分,確定目錄層次結構
–app 命令行應用
–data 存放數據上傳
–lib 庫函數
–template 模板
–conf 各種配置
–doc 文檔,SQL
–log 日志
–test 測試代碼
–ctemplate 編譯后的模板
–htdocs Web主目錄
大家能看到,htdocs 同其他目錄,比如 doc、app目錄為什么要並列?這是安全性的考慮,想一想,否則的話,你的表定義被人下走了。你的后台程序,可能會被用戶執行。
2、其次來看一下類的層次結構。
下圖是應用程序各個類的分層。
最基層的應用程序類,其實就是一個骨架。包括了getParam(取得參數,無論命令行,還是Web訪問,都需要有參數分析)。checkParam(參數檢測)、checkAuth(權限檢測,比如是否是需要登錄的一個頁面)、outputPage等這些方法,全是空方話,但是由一個run方法串起來。如下:
public function run() { $this->getPara(); $this->checkPara(); $this->checkAuth(); $this->main(); $this->outputPage(); $this->exitApp(); }
應用程序基類DCore_BaseApp.php的子類又分為三個,一個負責命令行程序的處理DCore_ConsoleApp.php,另外一個負責像移動應用、開放平台Api之類的數據處理DCore_ApiApp.php ,而第三個,則是DCore_WebApp.php, 我們所在瀏覽器上所訪問的應用,由這個應用程序類派生出來頁面類。而DCore_AdminApp.php,是管理后台應用程序類的基類。因為后端一般有不一樣的權限認證機制。這樣也是為了把前后台的應用程序類區分得更加清楚。
這樣可以看到,整體結構非常清晰。
好,那最后我們再來看一下,需要編寫哪些類庫。
在我們的框架中,編寫了這些。
•1、常用工具函數庫
實現字符串的常用操作封裝,比如中文取字串,繁簡轉換、編碼轉換
•2、模板引擎
可以簡化為包含PHP,在我們自己開發的這個框架中,支持了模板編譯,其實模板編譯很簡單,就是將一些特定的語法,換成PHP代碼,然后還是包含PHP
•3、路由控制,靜態化
用戶可以將路徑改成搜索引擎更友好的路徑,程序也能解析正確。
•4、后端數據請求控制
用於對后端一些公用操作的封裝,比如數據庫,比如Memcached,這樣的封裝帶來的好處是,如果一旦發生升級或者替換的時候,修改的代碼相對最少。比如你不用到處去改mysql_query,只需要修改當前這個庫文件即可以了。
八、總結
好的,今天的課程就到這里。總結一下,我們講了如下幾點:
1、5月課程尤其是5月份框架課程的總結。總結了框架與架構的區別。
2、站在PHP框架之外,看框架,看框架的共同特征與功用。
3、以PHP框架為例,講框架所不能解決或者帶來的問題。
4、由於框架所帶來的問題,以性能、可擴展問題,相對嚴重,所以分析PHP性能 的改造方向,總結了六大點。
5、分別演示了這六大點的改進實踐。包括Yaf、Phalcon框架介紹,zephir的使用,以及HHVM。
6、匯總六大點的改進,並做了相關的性能評測。能看到,使用不同的技術差別巨大,所以我們要在穩定可靠的情況下,盡可能采用最好的技術。
7、最后講解了開發一個自有框架,一般都是一個什么樣的思路。