2019独角兽企业重金招聘Python工程师标准>>>

前几天我讲到在SqlParser中完成SQL的解析,我已经讲了distinct,field,table,group,order等的简单实现,那么怎么实现where呢,没有where,这个SQL一直还是不能运行的。

对于where,我们可以想一下,允许用户输入的参数如:

$this->where('uid > 1'),$this->where(array('uid' => array('gt' , 1)))

这几种形式,首先第一种,就是直接将这段SQL通过字符串传递过来,这种在where函数中只需要拼接一个WHERE子串即可。

对于传递的参数是数组的情况就比较复杂了,首先,对于最外层的array,它的形式应该是如下的:

array(条件,条件,条件....)

对于具体的某一个条件,它也是一个数组,如:

字段=> array(比较符,数值,连接符)

对于最简单的形式,如$this->where(array('uid' => array('gt',1)))它实际上被解析之后的SQL为:WHERE uid > 1,如果条件为多个:

$this->where(array('uid' => array('gt' , 1)),'password' => array('neq' , 'test')),它代表的意思是:WHERE uid > 1 AND password != 'test',我们没有写条件与条件之间的连接符,应该框架自己会默认有一个连接符,如AND。

由于对于符号:eq,neq,gt,gte等,我们需要将它解析成为如:=,!=,>,>=等,所以我们首先要定义一个函数来处理这个:

我们称这个函数为:_parseCompExp,这个函数的实现为:

private function _parseCompExp($exp) {if(is_string($exp)) {return str_replace(array_keys($this->_compExp),array_values($this->_compExp),$exp);}elseif(is_array($exp)) {$tmpArr = array();foreach($exp as $val) {$tmpArr[] = str_replace(array_keys($this->_compExp),array_values($this->_compExp),$val);}return $tmpArr;} else {//不能解析,直接返回return $exp;}}

为了扩展,我们不会将需要解析的参数写死,而是直接做成一个private的变量,如:

private $_compExp = array('neq' => '!=','gte' => '>=','lte' => '<=','notlike' => 'NOT LIKE','gt' => '>','lt' => '<','eq' => '=','like' => 'LIKE');

这个变量指定了每一个字符串代表的实际意义。

具体的where的实现是怎么样的呢,我刚才写了一个实现,虽然看着很恶心:

private function _where($where) {if(empty($where)) {return '';}if(is_string($where)) {return ' WHERE ' . $where;}elseif(is_array($where)) {$str = ' WHERE ';$arrLen = count($where);$count = 0;foreach($where as $key => $val) {$needJoinStr = true;$joinStr = ' AND ';if(preg_match('/^lt|lte|gt|gte|eq|neq|like|notlike$/i',$val[0])) {$command = $this->_parseCompExp($val[0]);$str .= (' ' . $key . ' ' . $command . ' ' . $val[1]);} elseif('in' === strtolower($val[0])) {if(is_array($val[1])) {$str .= (' ( ' . $key . ' IN ' . implode(',',$val[1]) . ')');} else {$str .= (' ( ' . $key . ' IN ' . $val[1] . ' ) ');}} elseif('between' === strtolower($val[0])) {$data = explode(',',$val[1]);$str .= (' ' . $key . ' BETWEEN ' . $data[0] . ' AND ' . $data[1] . ' ');} else {}if($count + 1 < $arrLen) {if(isset($val[2])) {$str .= (' ' . $val[2] . ' ');} else {$str .= ' AND ';}}$count ++;}return $str;} else {}}

由于这种比较符有这样几种:

第一种:>,=,<等,这种后面跟的数值只有一个,如 > 1,这种的解析是比较简单的,只要通过parseCompExp函数转换一下,然后字符串拼接即可。

第二种:IN,IN后面跟的参数个数不一定,所以需要判定后面传递的是数组还是字符串,如果是数组,那么需要通过,来explode成为字符串,如果是字符串,那就直接拼接即可。

第三种,Between,后面跟的参数肯定是两个, 由于我为了简单,所以指定了第二个参数为数值,第三个参数为连接符,所以只有在第二个参数中设置数组来解决这个问题,如: 'uid' => array('between',array(2,4))它代表的意思就是:uid between 2 and 4。

对于其他情况,暂不解析。

再后面就是判定一下是否需要连接符,如果需要连接符,并且设置了数组的第三个元素,那么直接拼接,否则拼接AND。

现在我们可以在模型中使用了,使用如下:

<?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')) ->where(array('id' => array('gt',1)))->select();}
}

当然,这种实现是不完善的,反正先这样吧!!!

本来一个完整的SQL不只是我们实现的这几个函数,为了简便,我就不讲后面复杂的内容了。

对于其他框架实现的如:1对多,多对1这种多表查询,你们可以自己想一下怎么实现。

后面我就粗略讲一下DbTable了,DbRelation我就不讲了,有兴趣去实现的童鞋可以自己试一下。

转载于:https://my.oschina.net/mingtingling/blog/98233

怎么一步步编写简单的PHP的Framework(二十一)相关推荐

  1. how to write a php framework,怎么一步步编写简单的PHP的Framework(十四)

    今天我说一下怎么在框架中over掉这些安全问题. 首先是SQL注入,这个如果你使用的是PDO,我觉得应该没什么问题,如果你使用的还是mysql_*等API,那么你可以在框架中实现bindParamet ...

  2. 怎么一步步编写简单的PHP的Framework(五)

    2019独角兽企业重金招聘Python工程师标准>>> 上一次我讲到使用自动导入可以实现一个类的延迟加载,这一次我想讲一下配置文件. 不知道大家注意了没有,前几篇文章我都没有涉及到配 ...

  3. 怎么一步步编写简单的PHP的Framework(十九)

    2019独角兽企业重金招聘Python工程师标准>>> 上一次我说了一下怎么从ModelBase通过Sql parse将SQL拆分,也就是解析的过程,今天我详细的说一下. 首先,我们 ...

  4. 一步步编写操作系统 71 直接操作显卡,编写自己的打印函数71-74

    一直以来,我们在往屏幕上输出文本时,要么利用bios中断,要么利用系统调用,这些都是依赖别人的方法.咱们还用过一个稍微有点独立的方法,就是直接写显存,但这貌似又没什么含量.如今我们要写一个打印函数了, ...

  5. SPL:一种编写简单、运行速度快的数据库语言

    数据库语言的目标 为了明确这个目标,我们需要先了解数据库是干什么的. 说到数据库,总是让人以为它主要是为了存储,因为它的名字中有"基"的部分.但实际上并非如此,数据库可以实现两个重 ...

  6. 实用c语言函数源码,C语言编写简单朗读小工具(有源码)

    原标题:C语言编写简单朗读小工具(有源码) 最近不少人在后台留言说学C都是面对枯燥的控制台程序,能不能体现一下C语言的实际用途,今天我们就理论结合实践一把:C语言结合VBS脚本编写一个简单的朗读小工具 ...

  7. python七夕快乐_python编写简单抽奖系统

    python编写简单抽奖系统 #!/usr/bin/env python #coding=utf-8 from Tkinter import * import time import random c ...

  8. python做好的程序如何变成小程序-使用python编写简单的小程序编译成exe跑在win10上...

    每天的工作其实很无聊,早知道应该去IT公司闯荡的.最近的工作内容是每逢一个整点,从早7点到晚11点,去查一次客流数据,整理到表格中,上交给素未蒙面的上线,由他呈交领导查阅. 人的精力毕竟是有限的,所以 ...

  9. python爬虫简单实例-Python 利用Python编写简单网络爬虫实例3

    利用Python编写简单网络爬虫实例3 by:授客 QQ:1033553122 实验环境 python版本:3.3.5(2.7下报错 实验目的 获取目标网站"http://bbs.51tes ...

最新文章

  1. 宏基因组公众号14天受邀原创-诚邀同行共享研究经验
  2. access检查为空函数
  3. 原生js判断css动画结束 css 动画结束的回调函数
  4. thymeleaf取model值_史上最详 Thymeleaf 使用教程
  5. log4j2 mybatis 显示 sql 和 结果集
  6. 25岁,一位女程序员的幸运几年
  7. set_error_handler() 重要用法
  8. 苹果内部文件曝光:iPhone SE3以外,还有大惊喜...
  9. alin39048错误原因_支付宝支付ALIN10146错误
  10. java swing 图片切换_在一个界面中要实现图片切换,用java要肿么实现??
  11. 计算机前置usb应用,电脑前置usb和后置usb的区别
  12. Bailian2787 算24【DFS】(POJ NOI0205-1789)
  13. kubernetes视频教程笔记 (11)-pod容器生命周期、Init容器
  14. mysql FROM_UNIXTIME 格式化MYSQL时间戳函数
  15. JSP酒店管理系统myeclipse开发mysql数据库bs框架java编程jdbc详细设计
  16. 计算机中f4的应用,电脑键盘中功能区的F2键F4键如何使用 电脑键盘中功能区的F2键F4键怎么使用...
  17. AngularJS中文入门教程
  18. “华为 30 岁以下员工仅占 28%”上热搜,网友:说好的 35 岁天花板呢?
  19. Python入门技巧
  20. SplendidCRM

热门文章

  1. Rancher的简单部署和使用
  2. python升级或者其他原因把yum搞坏了
  3. [js高手之路]深入浅出webpack教程系列9-打包图片(file-loader)用法
  4. leetcode --Minimum Depth of Binary Tree
  5. 谈谈跨界在软件开发中存在的意义
  6. 广东发展银行系统分析师面试问题
  7. PMCAFF产品经理社区原创专栏,产品圈的干货看这儿就够了
  8. 史上最详细的客服系统产品落地|后台产品经理的工作实例,有那么苦吗?
  9. iOS 问题整理04----Runtime
  10. linux系统相关硬件查询