我正在建立一个数据库类,并认为合并某种形式的SQL注入(inject)预防是一个好主意(duh!)。这是运行数据库查询的方法:

class DB
{
    var $db_host    = 'localhost';
    var $db_user    = 'root';
    var $db_passwd  = '';
    var $db_name    = 'whatever';

    function query($sql)
    {
        $this->result = mysql_query($sql, $this->link);
        if(!$this->result)
        {
           $this->error(mysql_error());
        } else {
            return $this->result;
        }
    }
}

类里面还有更多,但我为此而删减。我面临的问题是,如果我只使用mysql_real_escape_string($sql, $this->link);,那么它会转义整个查询并导致SQL语法错误。如何动态找到需要转义的变量?我想避免在我的主要代码块中使用mysql_real_escape_string(),而希望在函数中使用它。

谢谢。

最佳答案

问题在于,当您建立SQL查询时,为时已晚,无法通过查找变量来防止注入(inject)-否则它已内置在PHP中。

生成查询时,转义需要更早地完成。您可以使用查询构建类。

但是,我建议使用另一种方法-拥有一个提供数据库表作为对象的层,这是一个示例user object,它是从base db entity class派生而来的,它使用active record patterniterator pattern提供了到数据库的完整接口(interface)。

我将通过一些示例进行说明。整洁的事情是迭代器,因为您可以进一步抽象很多,并在行的后面进一步添加一些非常通用的类以提取数据。

使用以上方法创建用户记录:

$user = new DbUser();
$user->create();
$user->set_email('test@example.com');
$user->write();

读取用户记录:
$user = new DbUser();
$user->set_email('text@example.com');
if ($user->load_from_fields())
{
}

要遍历记录:
$user_iterator = DbUser::begin();
if ($user_iterator->begin())
{
    do
    {
         $user = $user_iterator->current();
         echo $user->get_email();
    } while ($user_iterator->next());
}

10-08 08:01
查看更多