上一次我把SqlParser這個類的主要結構講了一下,此次我就將這個類的函數編寫了。 php
按照上節課的內容,主要的函數有下面幾個: 數組
private function _where($where){} private function _field($field) {} private function _distinct($distinct) {} private function _table($table) {} private function _order($order) {} private function _group($group) {}
首先咱們說一下distinct函數,這個函數最終會返回字符串DISTINCT或者空串,咱們能夠想一下,這個函數傳遞的形參其實是很是簡單的,它只須要告訴框架我是否須要DISTINCT便可,因此在框架中只需作一個簡單斷定就好。 框架
現假設用戶傳遞的參數爲true或字符串'distinct'的時候表明用戶想使用'DISTINCT',那麼這個函數的實現就變成了這樣: 函數
private function _distinct($distinct) { return ((true === $distinct) || ('distinct' === $distinct)) ? 'DISTANCT' : ''; }這裏直接使用'distinct' === $distinct斷定仍是有點問題的,由於用戶有時候仍是會輸入相似'Distinct'這種字符串,若是按照上面的寫法,直接就返回空串了,可是用戶原本的想法是返回'DISTINCT'。
其實咱們還能夠把這個函數再簡化一下,在一個SQL中,若是用戶須要DISTINCT他纔會使用distinct函數,因此咱們能夠經過斷定傳遞的參數是否爲空來斷定: 測試
private function _distinct($distinct) { return empty($distinct) ? '' : 'DISTINCT'; }
若是這樣這樣寫,那麼還須要在execute方法中斷定一下傳遞的$options中是否有key等於'distinct'的元素,若是有,那麼調用_distintct方法的時候就傳遞一個非空的參數,不然直接傳遞一個null過來就行。 ui
說完了簡單的distinct,咱們再說一下field,它指明要查詢的元素,好比:select uid,password from user; this
對這個函數,實際上在調用的時候是有點複雜的,由於可能用戶是想全部的都抓取,即返回*,也有可能只返回部分數據,也有可能將某一個字符取別名。 spa
因爲這個函數的形式是: code
private function _field($field)
傳遞的形參有多是數組,有多是字符串,也有可能傳遞一個null,那麼咱們須要一個個去斷定。 orm
首先是爲null的狀況,表明的是查找全部的,即返回*。
而後是字符串,這種的處理很簡單,直接返回就好,如$this->field('uid,password'),傳遞的就是字符串'uid,password',這種實際上不太好。
而後就是傳遞數組,首先是array('uid','password')這種方式,這種也須要foreach一下,而後進行字符串拼接便可,元素之間經過,分隔。
若是傳遞的是array('uid' => 'test','password' => 'test') 那麼解析以後就要變成'uid AS test,password AS test',因此拼接的時候須要傳遞AS子串。
好了,分析完了以後,就直接亮代碼吧。
private function _field($field) { if(is_array($field)) { $arr = array(); foreach($field as $key => $val) { if(is_numeric($key)) { $arr[] = $val; } else { $arr[] = ($key . ' AS ' . $val); } } return implode(',',$arr); } elseif(is_string($field) && !empty($field)) { return $field; } else { return '*'; } }咱們再說一下table,這個函數指定要查詢的SQL的表,它傳遞的能夠是字符串,也能夠是數組,若是是字符串,咱們仍是不進行處理,若是是數組,和上面的同樣,也有可能有別名的狀況,因爲思路相似,我就不細講了,直接貼代碼了:
private function _table($table) { if(is_array($table)) { $arr = array(); foreach($table as $key => $val) { if(is_numeric($key)) { $arr[] = $val; } else { $arr[] = ($key . ' AS ' . $val); } } return implode(',',$arr); } else { return $table; } }對於group,實際上很簡單,它只是指定了按照哪一個元素來分組而已,因此也能夠一句話搞定:
private function _group($group) { return empty($group) ? '' : ' GROUP BY ' . $group; }
對於order,它只是指定了排序的方式,若是傳入的參數爲空,那麼框架也不處理,若是傳遞字符串,也不處理,只是將‘ORDER BY’字符串拼接上去便可,若是是數組,那麼和上面幾個函數同樣,也須要斷定是否key爲數字,由於若是key不爲數字也是可能的,好比array('test' => 'asc'),它表明的意思就是按照test遞增排序:
private function _order($order) { if(empty($order)) { return ''; } if(is_array($order)) { $arr = array(); foreach($order as $key => $val) { if(is_numeric($key)) { $arr[] = $val; } else { $arr[] = ($key . ' ' . $val); } } return ' ORDER BY ' . implode(',',$arr); } return ' ORDER BY ' . $order; }
指定了這些以後,咱們在模型中就能夠測試一下了,我剛纔寫的這幾個函數就是在一個模型中測試的,使用以下:
<?php class TestModel extends ModelBase { public function test() { $this->distinct()->where()->field(array( 'id' => 'uid','user' ))->table(array( 'user' => 'TEST','limits' ))->group()->order(array( 'test','test2' => 'asc' ))->select(); } }
這樣返回的SQL爲:SELECT id AS uid,user FROM user AS TEST,limits WHERE where ORDER BY test,test2 asc,雖然這樣的SQL仍是錯誤的,可是距離正確已經不久了。
因爲我一邊寫這個,一邊還要寫代碼(這些代碼都是現場寫的),因此消耗的時間比較多,並且也可能會有一些錯誤,但願你們見諒!!
今天的代碼點此下載