六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 133|回复: 0

Zen-cart 数据库封装类解读

[复制链接]

升级  20.33%

79

主题

79

主题

79

主题

举人

Rank: 3Rank: 3

积分
261
 楼主| 发表于 2013-2-7 01:36:32 | 显示全部楼层 |阅读模式
要操作数据库,一般步骤基本如此,首先建立到数据库管理系统的连接,然后选择数据,接着就是操作数据库。首先看看queryFactory类,看看1.3.9版本连接数据库系统的改进:

view source
print?01 $connectionRetry = 10;  

02 while (!isset($this->link) || ($this->link == FALSE && $connectionRetry !=0) )  

03 {  

04   $this->link = @mysql_connect($zf_host, $zf_user, $zf_password, true);  

05   $connectionRetry--;  

06 }  

07 if ($this->link) {  

08   if (@mysql_select_db($zf_database, $this->link)) {  

09     if (defined('DB_CHARSET') && version_compare(@mysql_get_server_info(), '4.1.0', '>=')) {  

10       @mysql_query("SET NAMES '" . DB_CHARSET . "'", $this->link);  

11       if (function_exists('mysql_set_charset')) {  

12         @mysql_set_charset(DB_CHARSET, $this->link);  

13       } else {  

14         @mysql_query("SET CHARACTER SET '" . DB_CHARSET . "'", $this->link);  

15       }  

16     }  

17     $this->db_connected = true;  

18     return true;  

19   } else {  

20     $this->set_error(mysql_errno(),mysql_error(), $zp_real);  

21     return false;  

22   }  

23 } else {  

24   $this->set_error(mysql_errno(),mysql_error(), $zp_real);  

25   return false;  

26 }

这段代码比1.3.8的连接逻辑更加的缜密了,首先尝试10次连接数据系统,1.3.8中只要连接一次连接不上就回显错误,不管怎样,尝试多次连接,应该是合理的。另外新版本中引进了DB_CHARSET常量,让我们可以自己指定数据的字符编码,在1.3.8中,默认并没有这个考虑,这也就是一些乱码产生的本质原因,但是Zen-cart中文版中为了对付这个问题,加入了mysql_query(‘SET NAMES “utf8″‘, $this->link)这个语句,相比之下,原作者的水平还是技高一筹啊……

接下来再看看这个方法:

view source
print?1 function prepare_input($zp_string) {  

2   if (function_exists('mysql_real_escape_string')) {  

3     return mysql_real_escape_string($zp_string, $this->link);  

4   } elseif (function_exists('mysql_escape_string')) {  

5     return mysql_escape_string($zp_string, $this->link);  

6   } else {  

7     return addslashes($zp_string);  

8   }  

9 }

这个函数用于对数据进行转义,保证数据安全。这可正所谓是榨干了油的顾虑啊,同时也知道应该先用mysql_real_escape_string()再用mysql_escape_string()实在不行再用addslashes()。

可以说,这个类中的Execute函数是最核心的,先看这个函数开始的这段代码:

view source
print?01 // bof: collect database queries  

02 if (defined('STORE_DB_TRANSACTIONS') && STORE_DB_TRANSACTIONS=='true') {  

03   global $PHP_SELF, $box_id, $current_page_base;  

04   if (strtoupper(substr($zf_sql,0,6))=='SELECT' /*&& strstr($zf_sql,'products_id')*/) {  

05     $f=@fopen(DIR_FS_SQL_CACHE.'/query_selects_' . $current_page_base . '_' . time() . '.txt','a');  

06     if ($f) {  

07       fwrite($f,  "\n\n" . 'I AM HERE ' . $current_page_base . /*zen_get_all_get_params() .*/ "\n" . 'sidebox: ' . $box_id . "\n\n" . "Explain \n" . $zf_sql.";\n\n");  

08       fclose($f);  

09     }  

10     unset($f);  

11   }  

12 }  

13 // eof: collect products_id queries

刚开始真让人摸不着北,其实这段代码就是记录数据库查询,对应后台 日志选项->保存数据库查询,系统默认是false,也没有必要打开,否则每次查询将被保存一条日志信息,应该来说,这些信息没有太多用处。

接下来这个函数首先根据传递进来的参数$zf_cache判断这个查询是否需要缓存,如果如果需要缓存和查询已经被缓存并且缓存还没有过期,就把缓存内容吸收回来填充,否则如果没有缓存文件或者缓存文件过期,但是指定查询需要缓存,那么先删除已经缓存的文件(如果有),然后获取查询数据,接着缓存这个结果集,再否则的话就直接返回查询数据。从这个源码可以看到,Execut函数最后是用来查询,由于其里面也是使用mysql_query执行SQL语句,如果是INSERT这样的操作,同样也是可以被执行的,只是在$obj->RecordCount() > 0这个条件时,返回了false,所以并没有什么影响,事实上,这个类中也实现了另一个方法叫perform(),专门用来对付insert和update,这个函数只是execute函数的封装,只是它添加了调试跟踪的机制,看起来,它似乎更好,但是对我习惯了SQL语句,并且对SQL语句有十足把握能力的来说,我更喜欢直接控制SQL语句,我并不想变得更加傻瓜…..

现在来看看queryFactoryResult类,这个是一个查询结果集,主要两个函数,RecordCount返回记录数,MoveNext移动到下一条记录,这个类的对象数据在查询时被填充。从这个层次来说,Zen-cart里面的类,只是为了更加方便的集中函数,类之间的关系比较松弛,没有真正按照面向对象的思维来组织类,总之,Zen-cart本身就是一个面向过程设计思维设计出来的系统,虽然中间用了很多类,不过它只不过是为了更加方便的集中函数,如此而已。




本文转自:http://ifeeline.com/archives/207

意外看到的感觉不错就借鉴一下。
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表