首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用PHP的反射类来执行MySQL查询安全吗?

使用PHP的反射类来执行MySQL查询安全吗?
EN

Stack Overflow用户
提问于 2015-10-08 04:57:00
回答 2查看 482关注 0票数 0

背景

我一直在从头开始开发一个内容管理系统。由于经验的原因,它主要是从零开始开发的,但它也将在以后使用。

我用PHP语言开发了一个扩展mysqli类的DatabaseManager类。我正在使用它做MySQL查询和连接。我开发的一个函数传递SQL查询字符串(已参数化),后跟要替换的正确值的数组。

TL;DR

长话短说,我使用ReflectionClass将参数绑定到SQL查询和执行。我很好奇这是一种安全的方法,还是有另一种最适合的方法?

该方法

这是DatabaseManager::do_query()方法:

代码语言:javascript
复制
function do_query($sql, $values){
    if(!isset($this->connect_error)){
        $num_vals = count($values);
        $i = 0;
        $type = "";
        while($i < $num_vals){
            if(is_int($values[$i]) == true)
                $type .= "i";
            elseif(is_string($values[$i]) == true)
                $type .= "s";
            $i++;
        }

        $i = 0;
        while($i < $num_vals){
            $values2[$i] = &$values[$i];
            $i++;
        }
        $values2 = array_merge(array($type), $values2);

        $expr = $this->prepare($sql);
        if($expr != false){
            $ref = new ReflectionClass('mysqli_stmt');
            $method = $ref->getMethod("bind_param");            
            $method->invokeArgs($expr, $values2);

            $expr->execute();
            return "Success";
        }else{
            $error_string = "Error: Query preparation resulted in an error. ";
            $error_string .= $this->error;
            __TGErrorHandler(TG_ERROR_DB_PREP);
            return $error_string;
        }

    }
}

通过测试,我没有遇到任何直接的错误,而且它似乎可以阻止SQL注入,使用准备好的语句。但是,这个方法的结构有什么潜在的问题吗?

附注:我正在以一种不同的方式处理SELECT语句。这将主要处理DELETEINSERT语句。

EN

回答 2

Stack Overflow用户

发布于 2015-10-08 13:09:34

首先,你在正确的轨道上。只有少数人,可能是每一百个PHP用户中就有一个想要使用这样一个有用的功能。

接下来,反射对于这个任务来说是多余的,call_user_func_array()是一种可行的方法。Even though it's a little tricky,这是一种直接的方式,而反射不是。

最后,关于安全的问题。我将删除自动类型检测,并将所有参数绑定为字符串。这不会有任何坏处,但是如果您碰巧将一个数字与数据库中的字符串进行比较,那么使用您当前的方法,数据库可能会返回奇怪的结果。

这个函数中的错误处理也是有问题的。

票数 1
EN

Stack Overflow用户

发布于 2015-10-08 10:48:33

在这里使用反射没有什么不安全的地方,但这是完全不必要的。您可以使用call_user_func_array在没有反射的情况下完成完全相同的事情

代码语言:javascript
复制
if ($expr !== FALSE) {
    call_user_func_array([$expr, "bind_param"], $values2);
    $expr->execute();
    ...

或者,考虑使用PDO而不是mysqli。PDOStatement::execute()可以将绑定参数数组作为参数。(另外,使用PDO意味着您的代码可以移植到MySQL以外的数据库!)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33002277

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档