怎麼一步步編寫簡單的PHP的Framework(二十)

        上一次我把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仍是錯誤的,可是距離正確已經不久了。

    因爲我一邊寫這個,一邊還要寫代碼(這些代碼都是現場寫的),因此消耗的時間比較多,並且也可能會有一些錯誤,但願你們見諒!!

    今天的代碼點此下載

相關文章
相關標籤/搜索