Web 框架雜記

codeIgniter 將 控制器與模型 物件都定位在函式 的集合,比較接近靜態類別的函式集如 Math.abs ..Math.pie 。

django 則沒說明 控制器與模型 需要用物件來設計,給使用者自行抉擇的空間,都採用 module 內包含數 func 來實做, 但支援的 orm 可以讓存取資料表等同於物件的操作。

如果沒特別設計,依照兩個框架最原始的介紹與建議的基礎開發,兩者在控制器的差異不大,但 django 較沒有去解釋物件的用法,大都是用在各種工具元件的情況 如 Form , Session,因為原先物件導向的設計就比較偏向元件的重用,而不是函式的集合,所以 django 較符合原始意義。

那 codeIgniter 這樣設計有什麼好處呢?

將 PHP 按照順序執行的流程,整理成物件的生命週期,雖然異於物件導向原始的意義,但流程控制較容易掌控,在程式規模擴增時,也讓尋找程式碼實際檔案變的更加容易,且也提供 library 的方式來讓使用者擺放擴增的 classes。

但其 library 對於各式的 classes 的引入,不夠 friendly ,對檔案與類別名字有所限制。

整體來說,物件雖重用性不高,但對於限制程式擴增的模式來說,有良好的效果,如能搭配 modules 的概念,系統也能成長到一定的規模。

對於 php 還沒有支援命名空間的版本來說,當用 函式 來組織,很容易會有名稱的衝突,如果要退一步,就要用各種累贅的命名慣例,而透過多一層類別封裝函式,解決了這種情況,但遇到控制器與模型名稱衝突時,可能還是需要靠命名空間來解決,抑或是這種設計容易造成不具意義的物件(函式集),所以命名才會成為煩惱吧。

django 的彈性

….

codeIgniter Module 模組擴充

codeIgniter 的mvc模式,要分別在Controllers,views,models下分別建立對應的程式,實際上程式都是有單位的存在的,一個部落格會有blog_controller blog_models blog_views..等等 mvc 的程式,但被分散在三個資料夾,當程式的單位不只有 blog 而已,越來越多時就變的不太好管理。

剛開始在官網wiki上看到 http://codeigniter.com/wiki/Modular_Extensions_-_HMVC/ 這個library,他引入一種 HMVC 的觀念,將原始資料夾結構增加了 Modules 資料夾,並在內部每個資料夾下都有個 mvc 的資料夾,稱之為 Hierarchical-Model-View-Controller模式,也就是階層式的 MVC 引入一種模組的概念,每個子功能都是一個模組,分別管理維護,互不影響運作。

但是當初為了專案擴充的需要,想讓模組內還有模組,就無法單純使用這個 Lib 來滿足,有對他核心做些簡單的修改,但是其實這個library幾乎把 codeIgniter 核心都覆寫過了,所以更新 ci 版本時應該會有一些問題,後來發現一套 http://codeigniter.com/wiki/Matchbox/ matchbox,似乎提供更完整的載入函式,可以指定要載入的模組,但沒實際使用過,但看起來也一段時間沒更新了,而 hmvc 甚至還搬家了, http://bitbucket.org/wiredesignz/codeigniter-modular-extensions-hmvc,蠻久沒有看過他的更新,但 ci 模組的擴充應該就這兩套較完整。

如果要用 modules ~也可以考慮使用 Kahana 看看,他是 codeigniter 的分支但是內建支援以模組為單位。

PHP – null 妙用無窮…

  自從開始使用codeIgniter之後,在產生SQL時都藉由他的ActiveRecord來產生,一來是不用自己輸入又臭又長的SQL外,在某些時候又可以方便的將Update與Insert的差異降到很小,新增寫好要加上修改瞬間變得很容易,只需要補上一個條件式來分開處理ActiveRecord的最後一行。

  而當這種時候當然view也是同時可以共用的機會囉,將欄位的預設值都寫入於控制器撈出來的值以後,就可以共用同個介面將值都載入了,但是一直以來在這都有個難堪的地方不好解決,就是當要新增的時候自然不會有預設值,那預設值那些$value所產生的未定義變數的警告訊息要怎麼解決呢?

  最近在php看到剛好有人討論,可以透過將預設值的陣列丟入一個null來解決!實在是很神奇又簡單的解決這個問題,仔細想也挺有道理,雖不太理解null運作的細節,但還是大致可以理解為何可以運作,同時處理這兩件事變得輕鬆又優雅~!

codeIgniter with tcpdf , Integration 

tcpdf 是一套在php上很完整與活躍的開放原始碼程式,用於產生pdf函式庫,當要和codeIgniter搭配時好像沒那麼容易,需要有一個可直接連接的網址,官方wiki上有人寫了一個連接器,做了完整的接合,與設定的說明,

http://codeigniter.com/wiki/TCPDF-CodeIgniter_Integration/ 

但是裝上去以後發生了這個錯誤訊息,

Use of undefined constant K_CELL_HEIGHT_RATIO – assumed ‘K_CELL_HEIGHT_RATIO’

後來在這篇看到解決方案,http://codeigniter.com/forums/viewthread/133243/#661005

主要是這這回覆提出的,

I’ve seen this problem too, and I adjusted the tcpdf.php file around line 948 (version 4.6.013):

protected $cell_height_ratio = 1.25; //K_CELL_HEIGHT_RATIO;

So I just hardcoded the value 1.25 – got the value from tcpdf_config.php.

仔細追蹤後發現,為什麼會出現這個問題呢?

因為聯接器裡面主要在做的事就是重新定義他的config檔,放在codeIgniter的configs資料夾下,然後透過lib內的檔案將參數讀進來並設定初始化,在某個的tcpdf版本下可能可行,在5.3版下就發生了這個錯誤訊息,主要是因為常數集的定義順序,被這一行給破壞了,

protected $cell_height_ratio = K_CELL_HEIGHT_RATIO;

他寫在不是建構子的地方,所以定義常數時來不及在這個常數使用之前,所以我決定不改變原始程式碼,在lib內物件繼承上方寫上 define(‘K_CELL_HEIGHT_RATIO’, 1.25); 在較不破壞的情況下解決這個問題。

PHP Session codeIgniter Session 愛恨糾葛

  PHP Session從開始接觸PHP以後就一直是一個方便好用但是不容易理解的東西,如今開始使用Framework以後,內部擴充或外部擴充的library提供的額外功能又必須讓自己更瞭解Session運作的原理以後才能瞭解他,並且擴充他,否則會時常遇到莫名的session消失,令人苦惱。

  codeIgniter內建的session library實在不是太好用(在1.7.1版時),所以在網路上東找西找,找到的還可以接受的就是KNDB Session了。
  已經忘記比較的基礎跟找了哪些進行比較了,這篇主要不是要提這個,但比較時大略是觀察可否支援資料庫,是否與原生函式相容等等條件,http://bootleq.blogspot.com/2008/04/codeigniter-session-libs.html 主要是參考這篇文章的內容進行比較。
  而KNDB就是相容於$_SESSION也可擴充於資料庫等等的原因,實際跟其他使用起來感覺最順就選用了,只是印象好像在flash的部份有些bug有額外找資料修正,不曉得官方wiki版本是否修正了。

  接下來想要紀錄一下關於Session存活的一些參數,於KNDB中的參數內關於逾時的參數有兩個,觀察說明或原始碼後可以發現他們的意義:

sess_expiration:生存時間(LifeTime),Session最後存取時間超過此生存時間則會死亡。
sess_time_to_update:多久需要重新生成一次session_id,代表重送一次cookie 內的session_id,可以參考http://php.net/manual/en/function.session-regenerate-id.php內的說明。

  要真正瞭解這兩個參數需要從整個session運作的流程與方法才會完全理解。在下面試著做簡短又完整的說明:

  當瀏覽器一被session_start以後 php 會產生一個id 並於伺服器端建立一個檔案,然後將這id紀錄於使用者的cookie中,以確保使用者能在瀏覽區間內都可以與session檔案取得關聯以取得變數,在紀錄cookie的時後會有幾個參數發生作用
session.name:要用什麼名稱存於cookie中。
session.cookie_lifetime:這個cookie要存在瀏覽器多久的時間。
  接著使用者不停的在瀏覽器間換頁,直到發生了幾個事件,
session.gc_maxlifetime,session自從建立後假設超出了此時間,此session將會被視為垃圾,有一定機率被回收,回收機率則是 session.gc_probability / session.gc_divisor 這兩個參數所控制。
  或者是cookie超出session.cookie_lifetime的生存時間,則他的session_id就算還沒被回收,瀏覽器也會忘記他自己的session_id是什麼。

  如果瞭解這個流程之後,就可以搭配Session Library的參數進行瞭解,sess_time_to_update則是幫助你延遲cookie的lieftime,幫助你重新建立,而sess_expiration就是額外於原始php session中不可調整session存取時間與生存時間的擴充參數,但假設你的session.gc_maxlifetime沒有足夠長的時間,則不小心就被回收的話,這些參數就會變的無效用囉。

  所以可以透過於index.php中設置這些參數來調整,做更完整的session生存掌控。

ini_set(‘session.name’, ‘pissession’); // session值使用名稱
ini_set(‘session.gc_probability’, 5); // 回收處理分子項
ini_set(‘session.gc_divisor’, 100); // 回收處理分母項
ini_set(‘session.gc_maxlifetime’, 3600); // 清除以目前時間差中失效的過期session
ini_set(‘session.cookie_lifetime’, 0); // Cookie的SID存在時間

  最好是讓’session.gc_maxlifetime’與sess_time_to_update的時間有相對應的長度,否則sess_time_to_update有可能來不及重新產生session_id 就被回收掉囉。

  主要是這個運作的流程需要花費比較多時間去網路蒐集資料或閱讀數本書來了解,這篇就大略整理一下我對PHP Session目前的理解。