micro activerecord library in PHP(一個微型的PHP實現的AR庫)

來源:互聯網
上載者:User
一個微型的PHP實現的AR庫

體積很小帶詳盡的注釋總共只有400行
支援鏈式調用
支援關係

前言

最開始接觸ActiveRecord是在學習Yii的時候,那個時候覺得用AR操作資料庫真的是太方便了。以至於後來轉向其他的一些架構的時候,感覺沒有了AR似乎就不能操作資料庫了一樣!!!特別是中間自己使用一些簡單的說不上架構的東西來寫微型的PHP網站的時候,感覺手寫SQL太難看。
後來也接觸過一些優秀的獨立的ORM的庫,比如我最喜歡的idiorm. 甚至曾經萌生了想要把Yii的AR單獨拿出來用的想法!但是後來還是沒有實現。。。
在13年的時候,有一段時間上班時間太清閑,所以當時就想自己實現一個ActiveRecord類,一來打算練練手,而來也打算自己以後用的上。

準備

在開始動手寫之前,在github,以及stackoverflow上面尋找了一大堆的php的AR庫或者ORM的庫。

  • https://github.com/j4mie/idiorm

  • https://github.com/vrana/notorm

  • https://github.com/PrimalPHP/Record

  • https://github.com/spadgos/Record

  • https://github.com/sgoen/php.pdo.orm

  • https://github.com/jaceju/example-my-orm

  • 當然其中最好的就是idiorm以及notorm,在github上門分別有1600+和600+的star。
    拿idiorm來說,個人非常喜歡它提供的介面以及使用方式。而且整個庫也就單個檔案,雖然檔案將近2500行。但是已經算是一個小型的庫了。當然檔案有點長,看起來有點費勁。
    相對而言notorm設計得更加OO一些。不過在其中的NotORM_Result這個class中明顯看到一大片字串拼接SQL的方式,還是讓人覺得看起來不是很好。

    設計

    在看了一堆這樣的ORM的庫之後,非常反感那種直接拼接SQL的方式,但是這又是一個無法避開的問題,最後總是需要產生一個SQL字串的。
    關鍵在於需要找出一種比較”優雅“的方式來完成這個拼接的工作。

    運算式

    有一天在看拼接的SQL的時候偶然間感覺SQL裡面where後面的那些查詢條件總是一個一個的運算式(一個運算元加上一個操作符再加上一個運算元,例如:name='demo' and email='demo@demo.com')。

    這個運算式的結構看起來和數學裡面的(1+1)*(2+2)是那麼的相像。

    甚至連and,or也是一個一個的操作符而已。再提煉一下除了二元運算式,還有一元運算式(只有一個運算元的運算式,類似數學裡面的-1)。這樣算起來SQL裡面的select,from,where,delete,update這樣的關鍵詞都可以算成是”操作符“了。

    那麼一個簡單的SQL就可以分解成一個一個的運算式:

    select email, password from `user` where email = 'demo@demo.com';
  • select email, password

  • from user

  • where email = 'demo@demo.com'

  • email = 'demo@demo.com'

  • 上面的SQL總共拆分出來了4個運算式,其中where部分是嵌套的一個運算式。

    實現

    Expressions

    所以,我專門定義了一個Expressions類用來表示SQL中的各個部分。這個類只有一個__toString方法在最後需要的時候產生SQL

    class Expressions extends Base {    public function __toString() {        return $this->source. ' '. $this->operator. ' '. $this->target;    }}

    當然還有比較特殊的運算式就是"()",這個運算式特殊在於操作符是分開的。

    介面

    當提煉出來了運算式的類之後,那麼在使用ActiveRecord查詢資料庫的時候,每輸入一個動詞,都只是在適當的地方插入一個運算式而已。只有在最後的時候才會一次性的調用每一個運算式的__toString方法組合SQL,為了安全考慮,使用了PDO的綁定參數的形式防止SQL注入的風險!
    比如:

    $user->equal('id', 1);只是在where子句裡面產生了一個 "id=:ph1"的運算式,同時儲存了一個array(':ph1'=>1)的參數而已。同樣的還提供了簡寫的”eq“以及”ne“,”ge“等介面函數。另外還有”select“,”from“,”group“,”order“,”limit“,”top“以及”where“等介面函數。

    魔術方法

    為了減少代碼量,所以這裡使用了__call魔術方法避免了為每一個動作都去定義個method。

    關係

    除了實現SQL的基本操作,還實現了一下類似Yii的ActiveRecord法讓Relation的方法可以簡單的通過主外鍵關係查詢資料。
    定義了”HAS_ONE“,”HAS_MANY“和”BELONGS_TO“三種關係。
    可以在定義關係之後,能通過簡單的的訪問屬性的方式獲得關聯的資料。

    項目

    項目地址:https://github.com/lloydzhou/activerecord
    文檔地址:https://lloydzhou.github.io/activerecord
    已經提交到packagist.org可以通過composer安裝

    composer require lloydzhou/activerecord

    DEMO

    為了一邊測試,一邊完善這個庫。所以使用這個庫結合另外一個Router和 MicroTpl 寫了一個簡單的 部落格 ,裡面基本涵蓋了這幾個庫的API。

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.