怎么一步步编写简单的PHP的Framework(二十一)
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(二十一)相关推荐
- how to write a php framework,怎么一步步编写简单的PHP的Framework(十四)
今天我说一下怎么在框架中over掉这些安全问题. 首先是SQL注入,这个如果你使用的是PDO,我觉得应该没什么问题,如果你使用的还是mysql_*等API,那么你可以在框架中实现bindParamet ...
- 怎么一步步编写简单的PHP的Framework(五)
2019独角兽企业重金招聘Python工程师标准>>> 上一次我讲到使用自动导入可以实现一个类的延迟加载,这一次我想讲一下配置文件. 不知道大家注意了没有,前几篇文章我都没有涉及到配 ...
- 怎么一步步编写简单的PHP的Framework(十九)
2019独角兽企业重金招聘Python工程师标准>>> 上一次我说了一下怎么从ModelBase通过Sql parse将SQL拆分,也就是解析的过程,今天我详细的说一下. 首先,我们 ...
- 一步步编写操作系统 71 直接操作显卡,编写自己的打印函数71-74
一直以来,我们在往屏幕上输出文本时,要么利用bios中断,要么利用系统调用,这些都是依赖别人的方法.咱们还用过一个稍微有点独立的方法,就是直接写显存,但这貌似又没什么含量.如今我们要写一个打印函数了, ...
- SPL:一种编写简单、运行速度快的数据库语言
数据库语言的目标 为了明确这个目标,我们需要先了解数据库是干什么的. 说到数据库,总是让人以为它主要是为了存储,因为它的名字中有"基"的部分.但实际上并非如此,数据库可以实现两个重 ...
- 实用c语言函数源码,C语言编写简单朗读小工具(有源码)
原标题:C语言编写简单朗读小工具(有源码) 最近不少人在后台留言说学C都是面对枯燥的控制台程序,能不能体现一下C语言的实际用途,今天我们就理论结合实践一把:C语言结合VBS脚本编写一个简单的朗读小工具 ...
- python七夕快乐_python编写简单抽奖系统
python编写简单抽奖系统 #!/usr/bin/env python #coding=utf-8 from Tkinter import * import time import random c ...
- python做好的程序如何变成小程序-使用python编写简单的小程序编译成exe跑在win10上...
每天的工作其实很无聊,早知道应该去IT公司闯荡的.最近的工作内容是每逢一个整点,从早7点到晚11点,去查一次客流数据,整理到表格中,上交给素未蒙面的上线,由他呈交领导查阅. 人的精力毕竟是有限的,所以 ...
- python爬虫简单实例-Python 利用Python编写简单网络爬虫实例3
利用Python编写简单网络爬虫实例3 by:授客 QQ:1033553122 实验环境 python版本:3.3.5(2.7下报错 实验目的 获取目标网站"http://bbs.51tes ...
最新文章
- 宏基因组公众号14天受邀原创-诚邀同行共享研究经验
- access检查为空函数
- 原生js判断css动画结束 css 动画结束的回调函数
- thymeleaf取model值_史上最详 Thymeleaf 使用教程
- log4j2 mybatis 显示 sql 和 结果集
- 25岁,一位女程序员的幸运几年
- set_error_handler() 重要用法
- 苹果内部文件曝光:iPhone SE3以外,还有大惊喜...
- alin39048错误原因_支付宝支付ALIN10146错误
- java swing 图片切换_在一个界面中要实现图片切换,用java要肿么实现??
- 计算机前置usb应用,电脑前置usb和后置usb的区别
- Bailian2787 算24【DFS】(POJ NOI0205-1789)
- kubernetes视频教程笔记 (11)-pod容器生命周期、Init容器
- mysql FROM_UNIXTIME 格式化MYSQL时间戳函数
- JSP酒店管理系统myeclipse开发mysql数据库bs框架java编程jdbc详细设计
- 计算机中f4的应用,电脑键盘中功能区的F2键F4键如何使用 电脑键盘中功能区的F2键F4键怎么使用...
- AngularJS中文入门教程
- “华为 30 岁以下员工仅占 28%”上热搜,网友:说好的 35 岁天花板呢?
- Python入门技巧
- SplendidCRM