怎么一步步编写简单的PHP的Framework(二十二)

本文详细介绍了如何通过自定义函数实现SQL的基本操作如select、insert、update和delete,并探讨了DbTable模型的设计与实现,包括如何自动识别表名及简化SQL语句的构造。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       之前我们说了一下SqlParser这个类的execute怎么实现的,实际上这个函数叫execute是不合适的,因为它只能完成select操作,而update,insert,delete操作是不能完成的,最好将其修改为select,这样从名字上就很容易看出它的含义。

      实际上我们现在只是实现了select的解析,而这种解析现在也很不完善,比如having,limit这种就没有加进来,如果有join操作,这种更完不成,如果你们有兴趣,可以自己下去再好好扩展一下,实际上基本思路还是不难的。

     相对于select,update,insert,delete就不是很难了,一个基础的update为:UPDATE :table SET :condition :where,那么实际上这种函数只需要将update的SQL模板的:table,:condition部分的数据替换即可,:table部分可以使用SqlParser的_table这个方法,而:condition就需要重新编写了,:where复用SqlParser的_where方法。

     insert也很类似,INSERT INTO :table :condition,:table还是复用SqlParser的_table方法,而:condition需要重写,对于delete,基本的为:DELETE FROM :table :where,这个地方的:table可以复用SqlParser的_table方法,:where可以复用SqlParser的_where方法。

    假设现在select,insert,update,delete都完成了,那么一些基本操作就变得很简单了。

    select:   


$this->where(array( 'tid' => array('gt',2 ))->table('test')->select();


    update:


$this->table('test')->where(array(
    'tid' > array('gt',1)
))->update(array(
     'test' => 'aaaaa'
));


   insert:


$this->table('test')->insert(array(
   'tid' => 2,
   'test' => 'bbb'
));


   delete:  


$this->table('test')->where(array(
   'tid' => array('gt',2)
))->delete();


   我们知道,用户可访问的是DbTable,DbRelation,而这两个都是继承了ModelBase,分别为不同的模型实现了一些基础的功能,那么它是怎么弄的呢?

   我们以DbTable举例,DbTable是一个表模型,那么它必须有一个字段唯一标识这个模型,这就是表的主键,当然,也存在那种多个字段为主键的情况,我们这儿就不讨论了。

   之前我也说过了,DbTable有四个比较重要的变量,它们是protected的:

 

protected $_pk = null;
	protected $_tableInfo = array();
	protected $_tablePrefix = '';
	protected $_tableName = '';


   $pk标识主键,$_tableInfo记录表的字段名,$_tablePrefix标示表的前缀,$_tableName是逻辑表名,也就是没有加前缀的表明,如果一个表的实际表名为t_test,那么$_tablePrefix为t_,$_tableName为test。

   这儿我们定义一个useTable函数,它可以将逻辑表名转换为物理表名:


public function userTable($table) {
		return $this->_tablePrefix . $table;
	}
     然后我们来实现以下select,如果调用ModelBase,那么必须制定table,否则这个SQL就是错误的,但是在DbTable中,应该框架可以自动识别,那么一个简单的SQL就可以这么使用了:



$this->select();


    这个就会被解析为:select * from test。

    那么这个select函数怎么编写呢,其实就是判定一下$_options里面是否指定了table,如果没有,那么指定一下默认的表,然后就调用父类的select。

    具体的实现如下:

 

public function select() {
		if('' === $this->_options['table']) {
			$this->_options['table'] = $this->_tablePrefix . $this->_tableName;
		}
		parent::select();
	}


     简单吧,但是注意哦,之前我们编写ModelBase的时候,$_options是设置为了private,现在需要将其修改为protected。

     关于insert,update,delete实际上思路都很类似,由于这几个函数都需要使用到设置默认的表,所以可以将这句话独立为一个函数。

     这样看来,DbTable实际上非常简单,它不做具体的实现,只是调用接口完成功能即可,刚才我们都是通过函数链执行SQL,而我个人感觉对于复杂的SQL,用这种方式效率很低下,所以我建议使用execute方法,这个方法会直接调用驱动类的execute方法,而不经过SqlParser这一层。当然,如果你觉得对于简单的SQL,这种方式也是不可忍受的,你也可以所有SQL都使用execute。

     DbTable我就这样一笔带过了,DbRelation我就不讲了,关于模型我就说这么多了,我讲的比较快,实际上中间还是有很多问题需要考虑的,大家可以自己琢磨琢磨。

     为什么我要这么讲这么快呢,因为我马上要离开公司,回家之后由于没有网络,就写不了这个了,那样最快更新也要下学期了,很麻烦,所以尽量在走之前搞定!!!


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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值