天天看點

PHP開發架構比較PHP開發架構比較 開發運作效率示例: 綜述:

Laravel 是一個簡單優雅的 PHP WEB 開發架構,将你從意大利面條式的代碼中解放出來。通過簡單、優雅、表達式文法開發出很棒的 WEB應用!

但是通過使用我們發現Laravel在開發效率和運作效率上都存在瓶頸。如此優秀的架構都存在諸多問題,基于此我們在公司現有架構的基礎上參照諸多架構(不限于php語言也參照java和ruby)的優點完成一個自主設計的架構。

自此,YYUC架構的開發團隊征集并完成組建,不斷的讨論、編碼、測試、内部開發和合作夥伴推廣;一個完整的版本就此形成。

特性

codeigniter

laravel

YYUC

比較

路由規則

約定加自定義,視圖需要手工指定。

約定加自定義。

不利用配置檔案的路由規則就可以自由的建構URL格式,一般的路由約定是:

類/方法/參數,這種約定不夠靈活,YYUC的路由實作上可以更靈活。

laravel的統一分發雖然使路由的定義更加靈活的,但是個人覺得沒必要。隻要層次設計好有利于SEO和使用者感官就好,沒有必要獨立定義。Laravel3之前開發和維護過程中查着路由表找控制器累不累啊。Laravel3之後解決了這個問題,有了自動路由的方法:Route::controller(Controller::detect());

類加載

手動指定加載的類,分為幫助類,和字典類等等。

自動加載。

插件形式自動加載,分為系統插件和使用者插件等。

類較少時三個架構的加載速度相差不大,YYUC是自動加載,不用開發人員手動指定。Laravel也是這一原理,codeigniter調用load方法和直接include差不多,代碼不夠簡潔明快。

對于YYUC插件類較多時如超出500動态加載每次都要從衆多檔案中抽出所需要的類檔案YYUC效率會有所下降。

如果工程特别大,通用類檔案特别多考慮以指定包名稱的方式加載。如果隻是單一子產品下用到的類可以将類下載下傳控制器檔案夾下,以"_"開頭,調用import方法加載該子產品的類,父子產品和子子產品的類可以通過指明路徑層級明确調用。

資料校驗

校驗方式靈活。校驗規顯得有些雜亂

校驗方式靈活,預置的校驗種類全面。

建議将送出的資料都封裝在模型中,有對應庫表的用資料庫模型,沒有的用簡單模型。重寫校驗方法實作校驗。有利于資料的統一管理,與此同時特定校驗的擴充性強。

各有優勢,codeigniter的類加載本來就很醜了,再加上不同方式的校驗規則,代碼顯的亂七八糟的。

可擴充性

類相對獨立,并入架構内部要加一些架構的執行個體化方法。

架構基本上都是靜态風格,太過個性化。把網絡上開源的類引入架構中會顯得格格不入。最好最為自定義的類放入項目中。要用這些類擴充架構就要對引入的類做大手術。

插件形式引入,對于大多輸的類通常隻需改下類的檔案名就可以自動被調用。

還是喜歡自己寫的架構,核心是核心插件是插件,核心越精簡越高效越好,插件越強大越靈活越好。網絡上這麼多優秀的經過驗證的類為什麼不直接引入其中呢。

安全性

安全機制強大

隻包含一般安全校驗,如跨站送出等

自認為安全機制強大

codeigniter可以說把能做的安全防範機制都做了,laravel與其說是個架構倒更像一個路由分發的核心。很多安全問題需要自己考慮。YYUC參考了struct,Thinkphp以及codeigniter的安全驗證方式,把能加的安全防範規則都加了,可能由于自己底層知識(包括php底層,web伺服器底層)的局限性還存在漏洞也是可能的。但是用YYUC發現漏洞可以第一時間改掉。用其他的架構,如果萬一有漏洞存在,要麼要修改他的核心代碼要麼要等待版本更新是神被動的。

先進行

傳統的MVC模式,但是Model層不夠靈活,與庫表資料的一一對應并不好。

最新的5.3+支援,先進的文法風格。顯得有些另類

傳統的MVC模式

laravel運用了最新的5.3規範,引入命名空間的概念,像namespace use等文法都是最新引入,但是部署上有局限性。laravel引入了類似JS的匿名函數回調機制,開發者可能要在思維角度上有所轉變。而且大量的回調更利于假設高性能的分發程式,不适合傳統的Web網站開發。是以laravel隻是底層運用了這些模式,對于開發者來說還是傳統的MVC模式。

資料庫支援

功能強大,全面支援。

PDO規範支援Mysql和Sqlserver不支援Oracle

隻支援Mysql

YYUC目前隻支援Mysql資料庫,但是封裝的DB類做了很好的多庫表,主從表的支援(主要參照的Thinkphp),超大資料量的系統也是可以應對的。對于其他資料庫以後版本想以插件的形式。在精而不在多。

效率與開銷

相應速度快,記憶體開銷一般。

相應速度較快,記憶體開銷稍大。

生産模式下相應速度快,記憶體開銷很小,開發模式下需要編譯速度會稍微慢一些。

個人認為對PHP來說,架構類的層級過多并不一定是好事。

PHP的初衷就是靈活開發快速相應,Http并不是常連接配接的,處理好每次請求也就處理好了整個網站,好的架構并不一定要設計成像Spring那樣包羅萬象。

下面的例子分别利用三種架構做了個資料插入到Mysql資料庫并查詢輸出的示例,示例隻是實作基本的增加查詢功能并沒有進行資料校驗。下面的例子中将展示不同架構代碼量的,公平起見運作效率的統計方法沒有用架構底層的調試類而是采用原生的php方法計算運作時間和記憶體使用量:

CREATE TABLE `test_article` (

  `id` int(11) NOT NULL auto_increment COMMENT '主鍵',

  `title` varchar(255) default NULL COMMENT '标題',

  `content` text COMMENT '内容',

  `updated_at` datetime default NULL,

  `created_at` datetime default NULL, --laravel必須這兩個字段(和Rails的一模一樣)

  PRIMARY KEY  (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

新增頁面:

<!doctype html>

<html>

<head>

       <meta charset="utf-8">

       <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">

       <title>測試新增</title>

</head>

<body>

<?php echo Form::open('test/new','POST');?>

标題:<?php echo Form::text('title',$title);?>

内容:<?php echo Form::text('content',$content);?>

<?php echo Form::submit('送出');?>

<?php Form::token()?>

<?php echo Form::close();?>

</body>

</html>

如果要實作表單自動填充的話還是要手動指定的有些麻煩

新增成功頁:

       <title>儲存成功</title>

<h1>儲存成功</h1>

展示頁面:

       <title>顯示資料</title>

标題:<?php echo $title?><br/>

内容:<?php echo $content?><br/>

<?php

class Article extends Eloquent {

       public static $table = 'test_article';

}

class Test_Controller extends Base_Controller {

       /**

        * 頁面展示

        */

       public function action_init()

       {

              return View::make('test.new');

       }

        * 儲存資料

       public function action_new()

              $title =  Input::get('title');

              $content = Input::get('content');

              $article = new Article;            

              $article->title = $title;

              $article->content = $content;             

              $article->save();

              return View::make('test.success');

        * 顯示資料

       public function action_show($id)

              $article = Article::find($id);

              return View::make('test.show',array('title'=>$article->title,'content'=>$article->content));

<?php $this->load->helper('form');?>

<?php echo form_open('test/tonew'); ?>

标題:<?php echo form_input('title');?>

内容:<?php echo form_input('content');?>

<?php echo form_submit('mysubmit', '送出');?>

</form>

同樣的表單自動填充也不省事,不對稱的标簽格式總讓人心裡不舒服

class Article_model extends CI_Model {

        * 構造函數

       public function __construct()

              $this->load->database();

        * 新增函數

       public function to_new()

              $data = array(

                            'title' => $this->input->post('title'),

                            'content' => $this->input->post('content')

              );    

              return $this->db->insert('test_article', $data);

        * 查詢一條資料

        * @param $id

       public function show_one($id)

              $query = $this->db->get_where('test_article', array('id' => $id));

             return $query->row_array();

無論怎樣類初始化後DB連接配接就建立了,而且資料查詢很不友善,完全抛棄了POJO類的概念,要手動加屬性這點開發效率上是無法和YYUC和laravel相比的。

class Test extends CI_Controller {

              parent::__construct();

              $this->load->model('article_model');

       public function init()

              $this->load->view('test/new');           

       public function tonew()

              $this->article_model->to_new();        

              $this->load->view('test/success');

       public function show($id)

              $data = $this->article_model->show_one($id);

              $this->load->view('test/show',$data);

<form action="new.html" method="post">

标題:{$article->text('title')}

内容:{$article->text('content')}

<button type="submit">送出</button>

{tk()}

标題:{h $article->title}<br/>

内容:{h $article->content}<br/>

安全起見,視圖中轉義要輸出的字元

簡單的資料處理,沒有驗證、虛拟字段填充與回填、複雜資料計算等操作,使用自動模型建構就好,是以完全沒必要自定義模型

初始化和新增:

if(Request::post()){

       //資料送出

       $article = new Model('article');

       if($article->load_from_post()->save()){

              Page::view('success');

}else{

       //初始化顯示

       $article = new SampleModel('article');

資料顯示:

$article = new Model('article');

if(!is_numeric(get(1)) || !$article->find(get(1))->has_id()){

       //資料不合法或者不存在跳轉到404頁面 上兩個架構判斷起來稍顯麻煩就沒寫 如果有這種情況上兩個架構會直接抛異常的

       goto_404();

已經自動內建阻止跨站送出子產品

三個架構均設定為生産模式。

新增展示:

記憶體使用情況:

2989432bytes

運作時間:

0.0533249378204秒

資料儲存:

3433792bytes

0.130746126175秒

3374368bytes

0.0524969100952秒

2643704bytes

0.054661989212秒

2471400bytes

0.158566141129秒

2572744bytes

0.0491800308228秒

1850760bytes

0.0474209499359秒

2076544bytes

0.090379867554秒

2075152bytes

0.0683400440216秒

laravel是非常優美和整潔的php架構,路由功能非常強大,更像一個路由核心,有着良好的請求分發和路由控制,代碼風格整齊劃一。但是似乎laravel擴充的功能太過簡單,沒有太多的具體實作。最重要的是所有請求都要走路由,看了它的2.x和3.x版新版本才有預設規則,最新版簡直就和ROR一模一樣,比如資料表結構什麼的連字段的要求都是一樣的,Rails雖好也不至于模仿的這麼真真切切。基于laravel的前台的各種控件很少,網上甚至沒有一個基于laravel的完整的例子。中文文檔還在翻譯中對于新人來說用laravel開發效率可能會大打折扣,而且laravel在安全性方面考慮的并不多這也是讓人頭疼的一部分,好像隻有一個防止跨站送出的過濾器。個人認為最重要的是選擇使用laravel人現在并不多。架構結構設計的非常優秀,但是還是稍顯複雜的,引入了最新的命名空間,和閉包回調的機制,每次請求要加載的檔案太多了或多或少的拖了性能,是以記憶體消耗方面laravel是最大的。

Codeigniter功能強大但是顯得又過于雜亂了,特别是控制器和視圖的對應上完全背離了約定大于配置這一原則,沒有Rails的外部包裹機制,内部引入也顯得頁面和代碼不分家。Codeigniter沒有模型類的自動裝載功能,實際開發起來效率就會有些低,視圖代碼不講究對稱讓人看了不順心。好像Codeigniter并沒有自動的POJO類的概念,Model類側很重Active Record模式,資料庫的操作很大程度上依賴了手寫。還有就是開發的時候沒有顯示的類調用,這樣就得不到IDE友好提示,開發效率上多少會有影響的。

其實所有MVC的架構機制是一樣,但是YYUC其中一個特點是按需加載,控制器是程式片段而不是一個類,通常的面向類的控制器如果對應10個請求的話那麼每次頁面請求都會無端的加載9段多餘的其他代碼。php不像Java常駐記憶體,每次請求能少加載些就少加載些。YYUC控制器中的變量是不需要顯示的聲明注入到視圖中的,視圖和控制器在同一個級别之下,這樣即提高了開發效率又加快了代碼的執行效率。YYUC的Model既有原始POJO類的特點也可以通過子類實作Active Record模式,可以在開發時靈活選擇。通過插件規則YYUC内置了很多常用控件,像分頁、日期,上傳,圖檔截取,驗證碼、顔色選取、富文本編輯器、HTML5的視訊音頻相容播放、HTML5的WebSocket相容支援等等。