最后更新于 .

好吧,因为组织需要,最近又开始转战php了,业务逻辑都还好说,主要是老大要求在数据访问层上加上登录态验证。
其实这种要求也是合理的,互联网服务要求上层保护下层,但下层不能完全相信上层。但是问题也就来了,有如下两种方案:

1.写一个mysql proxy server,用来将调用方发来的请求拼装,然后返回给调用侧。这样做的主要难度在于:

  • a)SQL语句的拼装及序列化
  • b)数据集序列化,虽然有不少这方面的产品,但是终究还是太过复杂,而且没有时间折腾

果断放弃。
2.封装一层mysql的api,调用方直接在本地调用即可。这样的话,只需要考虑SQL语句的拼装即可。现在就有很多选择啦,

  • a)使用类似django里面Model的模型类
  • b)使用ci中的Active Record

虽然说Model的方式,对数据层的屏蔽较好,但是小组成员普遍认为这种方式过重,轻量的一点的话,最终还是选择了CodeIgniter中的AR。
OK,那么现在,考验ci模块拆分的好不好的时候到啦!
具体中间的种种辛苦就不说啦,直说我最终的实现把,拷贝system\database到一个单独的目录,x:/php/ 。
创建一个文件myconfig.php:

<?php
define('BASEPATH', dirname(__FILE__).'/');
define('EXT', '.php');
require_once(BASEPATH . 'database/DB' . EXT);

function &instantiate_class(&$class_object)
{
    return $class_object;
}

function log_message($level = 'error', $message, $php_error = FALSE)
{
    echo($message);
}
function MYDB()
{
    $params = array(
        'dbdriver'  => 'mysql',
        'hostname'  => 'localhost',
        'username'  => 'root',
        'password'  => '',
        'database'  => 'dante',
        'pconnect'  => TRUE,
        'db_debug'  => FALSE,
        'cache_on'  => FALSE,
        'char_set'  => 'utf-8',
        'dbcollat'  => 'utf8_general_ci',
    );
    $db = DB($params,TRUE);    
    return $db;
}
?>

创建一个测试文件test.php:

<?php
require_once('myconfig.php');
$db = MYDB();
$db->select('ID,user_login,user_email');
$query = $db->get('wp_users');
echo "\n";
foreach ($query->result() as $row)
{
    print $row->ID . "\n";
    print $row->user_login . "\n";
    print $row->user_email . "\n";
}
?>

输入结果如下:

Database Driver Class Initialized
1
admin
zny2008@gmail.com

OK啦~~~ 这样我们如果要在数据访问前需要做权限校验的话,只需要在MYDB函数中做判断即可。
另外,不得不说ci模块拆分的确实不错,instantiate_class是来自于它的system\codeigniter\Common.php。log_message我给重写了一下,因为对于每个调用者来说,希望写log的方式是不一样的。(比如我这次就直接打印在了屏幕上。。。。),最近正好在看设计模式,这种方式也是符合模版方法模式的。
ps:
《php敏捷开发框架CodeIgniter - 快速web应用开发详解》这本书中关于ar的用法中的例子居然是错的,害得我看源码才发现问题,书中的例子是这样的:

$this->db->select('url','name','clientid','people.surname AS client');

而实际应该是这样的:

$this->db->select('url,name,clientid,people.surname AS client');

代码下载(以后代码都会像这样,统一放到google code上下载):
http://vimercode.googlecode.com/svn/trunk/ci_model/ ----------------------------------------------------------
补充一下,当数据库链接出现问题的时候,会调用DB_driver.php中的display_error函数,里面会调用更多的类,为了不引入太多的类,直接改成:

function display_error($error = '', $swap = '', $native = FALSE)
{
    echo "数据库链接出错,请稍候再试";
    exit;
}

 

Pingbacks

  1. Thinking In LAMP Blog &raquo; Blog Archive &raquo; on #

    [...] http://www.vimer.cn/2010/11/%E6%8A%BD%E7%A6%BBcodeigniter%E7%9A%84%E6%95%B0%E6%8D%AE%E5%BA%93%E8%AE%... 抽离CodeIgniter的数据库访问类! [...]

  2. 更简洁的C++数据库访问框架-soci | Vim中文网 on #

    [...] 后来有幸在php中找到codeigniter的ActiveReord,详细参考这篇文章: 抽离CodeIgniter的数据库访问类! [...]

Pingbacks已打开。

Trackbacks

引用地址

评论

  1. hwywhywl

    hwywhywl on #

    请教vimer,如何设置TagList,才能能TagList显示出python 文件中的 (类,方法等)标签,我的TagList无法显示。

    Reply

    1. Dante

      Dante on #

      有配置好ctags吗?是只有python不能用,还是c,python,php都不能用?

      Reply

      1. hwywhywl

        hwywhywl on #

        呃!现在只能看到vimrc里定义得变量和函数,现在正在看vimer写的相关文章,再折腾 折腾吧,试试看是不是ctags配置问题?

        Reply

        1. Dante

          Dante on #

          呵呵,加油~~

          Reply

          1. hwywhywl

            hwywhywl on #

            Python 不行,C/C++ 可以,不知何解?望vimer指点。

            Reply

            1. Dante

              Dante on #

              我特意又试了一下,确实没问题的。。。
              是不是ctags的版本太老了?

              Reply

              1. hwywhywl

                hwywhywl on #

                不会阿,ctags5.8的啊,老不了哪里去,我不是很明白python需要怎么样去设置。难道死默认就支持?

                Reply

                1. Dante

                  Dante on #

                  我也是5.8,不需要任何配置的。。。

                  Reply

                  1. hwywhywl

                    hwywhywl on #

                    杯具啦!

                    Reply

  2. 秋风

    秋风 on #

    great,我怎么就没想过这个问题呢!!!!

    Reply

  3. 秋风

    秋风 on #

    CI源码是直接拿这个配置发送到mysql的!so,你myconfig.php文件中的,MYDB方法,$params['char_set']的值,应该是没有横线(utf8)的吧?

    Reply

    1. Dante

      Dante on #

      呃,很久的代码了,我直接的这里有没有-是有区别的,有一个是错的,还把外网环境写错了一次。。

      Reply

发表评论