上一次我把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仍是错误的,可是距离正确已经不久了。
因为我一边写这个,一边还要写代码(这些代码都是现场写的),因此消耗的时间比较多,并且也可能会有一些错误,但愿你们见谅!!
今天的代码点此下载