2008-11-13 63 views
8

我正在开发面向对象的PHP网站,并试图确定从系统其余部分抽象数据库功能的最佳方式。现在,我有一个DB类来管理系统使用的所有连接和查询(它几乎是MDB2的一个接口)。但是,在使用这个系统时,我意识到我的代码中随处可见很多SQL查询字符串。例如,在我的用户类中,我有这样的东西:从数据库功能中分离代码

function checkLogin($email,$password,$remember=false){ 
    $password = $this->__encrypt($password); 
    $query = "SELECT uid FROM Users WHERE email=? AND pw=?"; 

    $result = $this->db->q($query,array($email,$password)); 

    if(sizeof($result) == 1){ 
     $row = $result->fetchRow(MDB2_FETCHMODE_ASSOC); 
     $uid = $row['uid']; 
    }else{ 
     return false; 
    } 

    /* Rest of the login script */ 
} 

我想要做的是找出减少内联SQL的最佳技术。我明白,一种方法是在User中为每个用户使用的查询编写函数(如下所示),但这可能会导致相当多的函数。

function checkLogin($email,$password,$remember=false){ 
    $password = $this->__encrypt($password); 
    $uid = $this->do_verify_login_query($email,$password); 

    /* Rest of the login script */ 
} 

function do_verify_login_query($email,$encpw){ 
    $query = "SELECT uid FROM Users WHERE email=? AND pw=?"; 
    $result = $this->$db->q($query,array($email,$encpw)); 

    if(sizeof($result) == 1){ 
     $row = $result->fetchRow(MDB2_FETCHMODE_ASSOC); 
     return $row['uid']; 
    }else{ 
     return false; 
    } 
} 

所以......我的问题。管理典型数据库应用程序使用的大量查询的最佳技术是什么?我描述的方式是否是处理这种情况的正确方法?或者,在DB类中注册一个查询列表,并将每个传递到DB查询函数的唯一ID(例如USER_CHECKLOGIN)关联起来呢?这种方法也可以有助于安全性,因为它会限制只能在列表中注册的查询,但在编写所有类功能时还需要记住一点。思考?

回答

7

把SQL分解成单独的函数是一个体面的开始。您可以执行的其他操作:

  • 为数据库访问代码创建单独的类。这将有助于确保您的所有PHP文件中都没有SQL函数。
  • 从外部文件加载SQL。这完全分离了你的SQL代码和你的PHP代码,使两者更易于维护。
  • 尽可能使用存储过程。这将完全从您的PHP代码中删除SQL,并通过降低外部SQL执行的风险来帮助提高数据库安全性。
+0

存储过程是否需要内联SQL语句才能执行它们,因为它们只存在于数据库中?或者当我说使用存储过程时,我不明白你的意思吗? – cmptrgeekken 2008-11-13 03:52:14

+0

MySQL实际上只是添加了存储过程,而且我读过的语法并不像在SQL Server中那样灵活。海事组织,存储过程是真正无用的,除非你需要编写一个广泛或复杂的查询。 – Kevin 2008-11-13 04:03:10

4

您可能想要考虑实施ActiveRecord Pattern。使用诸如此类的设计模式,可以在处理来自表格的数据方面提供一致性。这些方法可能存在一些缺点,主要表现为某些类型的查询,但可以解决。

4

另一个选择可能是使用ORM的,PHP最强大的是:

都允许您使用一组对象的访问数据库,为存储和查询数据提供了一个简单的API,它们都有自己的查询语言,它们在内部被转换为目标DBMS原生SQL,这将简化将应用程序从一个RDBMS迁移到另一个RDBMS的简单配置。 nges。我也喜欢这样一个事实,即可以封装数据模型逻辑来添加验证,例如只通过扩展模型类。

3

既然你说你正在做OO PHP,那你为什么要把SQL分散到所有的方法中呢?更常见的模型是:

  1. 使用ORM并让它处理数据库。
  2. 为您的类提供一个或多个使用单个查询的“加载”方法将所有对象的数据拖入内存,以及使用单个查询更新数据库中的所有内容的“save”方法。所有其他方法只需要进行内存中操作,数据库交互仅限于加载/保存方法。

第一个选项通常会更健壮,但第二个选项可能会运行得更快,并且与您习惯做事的方式相比,可能会更加熟悉,如果其中任何一个都是担忧的话。

您的登录例如,我会做到这一点的话,会是简单地通过电子邮件地址加载用户,呼叫$user->check_password($entered_password),并抛出一个异常/返回false /如果check_password失败什么的。 check_password和任何登录处理代码都不需要关注数据库,或者甚至不知道数据库是用户从哪里加载的。

0

另一种选择是将查询视为数据并将它们存储在数据库中。例如,您可以创建一个存储带查询名称的查询表和存储该查询参数的另一个表。然后在PHP中创建一个函数,该函数使用查询的名称和一个参数数组并执行查询,返回任何结果。您还可以将其他元数据附加到查询以限制对某些用户的访问,对结果应用后期功能等。