


micro activerecord library in PHP(一個(gè)微型的PHP實(shí)現(xiàn)的AR庫(kù))
Jun 23, 2016 pm 01:25 PM一個(gè)微型的PHP實(shí)現(xiàn)的AR庫(kù)
體積很小帶詳盡的注釋總共只有400行
支持鏈?zhǔn)秸{(diào)用
支持關(guān)系
前言
最開(kāi)始接觸ActiveRecord是在學(xué)習(xí)Yii的時(shí)候,那個(gè)時(shí)候覺(jué)得用AR操作數(shù)據(jù)庫(kù)真的是太方便了。以至于后來(lái)轉(zhuǎn)向其他的一些框架的時(shí)候,感覺(jué)沒(méi)有了AR似乎就不能操作數(shù)據(jù)庫(kù)了一樣?。?!特別是中間自己使用一些簡(jiǎn)單的說(shuō)不上框架的東西來(lái)寫(xiě)微型的PHP站點(diǎn)的時(shí)候,感覺(jué)手寫(xiě)SQL太難看。
后來(lái)也接觸過(guò)一些優(yōu)秀的獨(dú)立的ORM的庫(kù),比如我最喜歡的idiorm. 甚至曾經(jīng)萌生了想要把Yii的AR單獨(dú)拿出來(lái)用的想法!但是后來(lái)還是沒(méi)有實(shí)現(xiàn)。。。
在13年的時(shí)候,有一段時(shí)間上班時(shí)間太清閑,所以當(dāng)時(shí)就想自己實(shí)現(xiàn)一個(gè)ActiveRecord類,一來(lái)打算練練手,而來(lái)也打算自己以后用的上。
準(zhǔn)備
在開(kāi)始動(dòng)手寫(xiě)之前,在github,以及stackoverflow上面尋找了一大堆的php的AR庫(kù)或者ORM的庫(kù)。
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
當(dāng)然其中最好的就是idiorm以及notorm,在github上門(mén)分別有1600+和600+的star。
拿idiorm來(lái)說(shuō),個(gè)人非常喜歡它提供的接口以及使用方式。而且整個(gè)庫(kù)也就單個(gè)文件,雖然文件將近2500行。但是已經(jīng)算是一個(gè)小型的庫(kù)了。當(dāng)然文件有點(diǎn)長(zhǎng),看起來(lái)有點(diǎn)費(fèi)勁。
相對(duì)而言notorm設(shè)計(jì)得更加OO一些。不過(guò)在其中的NotORM_Result這個(gè)class中明顯看到一大片字符串拼接SQL的方式,還是讓人覺(jué)得看起來(lái)不是很好。
設(shè)計(jì)
在看了一堆這樣的ORM的庫(kù)之后,非常反感那種直接拼接SQL的方式,但是這又是一個(gè)無(wú)法避開(kāi)的問(wèn)題,最后總是需要生成一個(gè)SQL字符串的。
關(guān)鍵在于需要找出一種比較”優(yōu)雅“的方式來(lái)完成這個(gè)拼接的工作。
表達(dá)式
有一天在看拼接的SQL的時(shí)候偶然間感覺(jué)SQL里面where后面的那些查詢條件總是一個(gè)一個(gè)的表達(dá)式(一個(gè)操作數(shù)加上一個(gè)操作符再加上一個(gè)操作數(shù),例如:name='demo' and email='demo@demo.com')。
這個(gè)表達(dá)式的結(jié)構(gòu)看起來(lái)和數(shù)學(xué)里面的(1+1)*(2+2)是那么的相像。
甚至連and,or也是一個(gè)一個(gè)的操作符而已。再提煉一下除了二元表達(dá)式,還有一元表達(dá)式(只有一個(gè)操作數(shù)的表達(dá)式,類似數(shù)學(xué)里面的-1)。這樣算起來(lái)SQL里面的select,from,where,delete,update這樣的關(guān)鍵詞都可以算成是”操作符“了。
那么一個(gè)簡(jiǎn)單的SQL就可以分解成一個(gè)一個(gè)的表達(dá)式:
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總共拆分出來(lái)了4個(gè)表達(dá)式,其中where部分是嵌套的一個(gè)表達(dá)式。
實(shí)現(xiàn)
Expressions
所以,我專門(mén)定義了一個(gè)Expressions類用來(lái)表示SQL中的各個(gè)部分。這個(gè)類只有一個(gè)__toString方法在最后需要的時(shí)候生成SQL
class Expressions extends Base { public function __toString() { return $this->source. ' '. $this->operator. ' '. $this->target; }}
當(dāng)然還有比較特殊的表達(dá)式就是"()",這個(gè)表達(dá)式特殊在于操作符是分開(kāi)的。
接口
當(dāng)提煉出來(lái)了表達(dá)式的類之后,那么在使用ActiveRecord查詢數(shù)據(jù)庫(kù)的時(shí)候,每輸入一個(gè)動(dòng)詞,都只是在適當(dāng)?shù)牡胤讲迦胍粋€(gè)表達(dá)式而已。只有在最后的時(shí)候才會(huì)一次性的調(diào)用每一個(gè)表達(dá)式的__toString方法組合SQL,為了安全考慮,使用了PDO的綁定參數(shù)的形式防止SQL注入的風(fēng)險(xiǎn)!
比如:
$user->equal('id', 1);只是在where子句里面生成了一個(gè) "id=:ph1"的表達(dá)式,同時(shí)保存了一個(gè)array(':ph1'=>1)的參數(shù)而已。同樣的還提供了簡(jiǎn)寫(xiě)的”eq“以及”ne“,”ge“等接口函數(shù)。另外還有”select“,”from“,”group“,”order“,”limit“,”top“以及”where“等接口函數(shù)。
魔術(shù)方法
為了減少代碼量,所以這里使用了__call魔術(shù)方法避免了為每一個(gè)動(dòng)作都去定義個(gè)method。
關(guān)系
除了實(shí)現(xiàn)SQL的基本操作,還實(shí)現(xiàn)了一下類似Yii的ActiveRecord法讓Relation的方法可以簡(jiǎn)單的通過(guò)主外鍵關(guān)系查詢數(shù)據(jù)。
定義了”HAS_ONE“,”HAS_MANY“和”BELONGS_TO“三種關(guān)系。
可以在定義關(guān)系之后,能通過(guò)簡(jiǎn)單的的訪問(wèn)屬性的方式獲得關(guān)聯(lián)的數(shù)據(jù)。
項(xiàng)目
項(xiàng)目地址:https://github.com/lloydzhou/activerecord
文檔地址:https://lloydzhou.github.io/activerecord
已經(jīng)提交到packagist.org可以通過(guò)composer安裝
composer require lloydzhou/activerecord
DEMO
為了一邊測(cè)試,一邊完善這個(gè)庫(kù)。所以使用這個(gè)庫(kù)結(jié)合另外一個(gè)Router和 MicroTpl 寫(xiě)了一個(gè)簡(jiǎn)單的 博客 ,里面基本涵蓋了這幾個(gè)庫(kù)的API。

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

TosecurelyhandleauthenticationandauthorizationinPHP,followthesesteps:1.Alwayshashpasswordswithpassword_hash()andverifyusingpassword_verify(),usepreparedstatementstopreventSQLinjection,andstoreuserdatain$_SESSIONafterlogin.2.Implementrole-basedaccessc

To safely handle file uploads in PHP, the core is to verify file types, rename files, and restrict permissions. 1. Use finfo_file() to check the real MIME type, and only specific types such as image/jpeg are allowed; 2. Use uniqid() to generate random file names and store them in non-Web root directory; 3. Limit file size through php.ini and HTML forms, and set directory permissions to 0755; 4. Use ClamAV to scan malware to enhance security. These steps effectively prevent security vulnerabilities and ensure that the file upload process is safe and reliable.

In PHP, the main difference between == and == is the strictness of type checking. ==Type conversion will be performed before comparison, for example, 5=="5" returns true, and ===Request that the value and type are the same before true will be returned, for example, 5==="5" returns false. In usage scenarios, === is more secure and should be used first, and == is only used when type conversion is required.

The methods of using basic mathematical operations in PHP are as follows: 1. Addition signs support integers and floating-point numbers, and can also be used for variables. String numbers will be automatically converted but not recommended to dependencies; 2. Subtraction signs use - signs, variables are the same, and type conversion is also applicable; 3. Multiplication signs use * signs, which are suitable for numbers and similar strings; 4. Division uses / signs, which need to avoid dividing by zero, and note that the result may be floating-point numbers; 5. Taking the modulus signs can be used to judge odd and even numbers, and when processing negative numbers, the remainder signs are consistent with the dividend. The key to using these operators correctly is to ensure that the data types are clear and the boundary situation is handled well.

Yes, PHP can interact with NoSQL databases like MongoDB and Redis through specific extensions or libraries. First, use the MongoDBPHP driver (installed through PECL or Composer) to create client instances and operate databases and collections, supporting insertion, query, aggregation and other operations; second, use the Predis library or phpredis extension to connect to Redis, perform key-value settings and acquisitions, and recommend phpredis for high-performance scenarios, while Predis is convenient for rapid deployment; both are suitable for production environments and are well-documented.

TostaycurrentwithPHPdevelopmentsandbestpractices,followkeynewssourceslikePHP.netandPHPWeekly,engagewithcommunitiesonforumsandconferences,keeptoolingupdatedandgraduallyadoptnewfeatures,andreadorcontributetoopensourceprojects.First,followreliablesource

PHPbecamepopularforwebdevelopmentduetoitseaseoflearning,seamlessintegrationwithHTML,widespreadhostingsupport,andalargeecosystemincludingframeworkslikeLaravelandCMSplatformslikeWordPress.Itexcelsinhandlingformsubmissions,managingusersessions,interacti

TosettherighttimezoneinPHP,usedate_default_timezone_set()functionatthestartofyourscriptwithavalididentifiersuchas'America/New_York'.1.Usedate_default_timezone_set()beforeanydate/timefunctions.2.Alternatively,configurethephp.inifilebysettingdate.timez
