扩展mysqli_stmt为5.2.17添加fetchAll?

时间:2012-11-26 21:12:23

标签: php mysql mysqli

php 5.2.17

mysqli准备语句结果绑定到变量。

想要扩展mysqli_stmt以添加自定义fetchAll方法。

为什么呢?因为想要停止为准备好的语句数据库结果编写相同的while语句,并将代码包含在mysqli本身中,以便自动处理所有调用。我还添加了自己的特殊代码和过滤器。

我已经能够扩展mysqli类并添加为非预处理语句执行此操作的自定义处理,但是希望将其添加到预处理语句处理中。

通过stackoverflow和其他地方读取我发现了一些扩展mysqli_stmt的例子,但没有类似于为php 5.2x添加fetchAll类型的自定义方法。

我不明白它是如何工作的,我对OOP有点新,并且扩展了核心的php类,并且会尽可能多地理解我所能学习的内容。

我的webhost有php 5.2.17,我无法控制,所以升级php不是一个选项。我创建了一个处理PDO,mysqli和mysql数据库连接的类。我正在尝试优化这一点,并尽可能地封装和移动到相关领域,因此我有兴趣这样做。

我理解结果类但是从我可以告诉我们获取预处理语句的处理是通过mysqli_stmt类完成的,它只有fetch来检索结果。我无法从本课程中获得结果,仅在外面。我假设由于绑定或参数和变量。我不完全理解这里的过程。

我回来的结果也与变量绑定,并通过while循环更新。我想把这个过程放在stmt类中,但我不明白怎么做。

感谢您提供的任何帮助。我很聪明,但我很难理解这个过程,所以如果你能解释得那么好。

感谢。

编辑:

我想在此添加以显示一些代码。

$mysqli->execute();     
$mysqli->store_result();
$mysqli->bind_result($id, $name, $age);                     

$i = 0;
While($mysqli->fetch()){            
    $array[$i]['id'] = $id;
    $array[$i]['age'] = $age;
    $array[$i]['name'] = $name;
    $i++;
}           

return $array;

查看While语句。

现在假设我想将它放入MYSQLI_STMT类中,这样我就不必一遍又一遍地编写它,只需让MYSQL_STMT类处理它。

这将进入一个名为FetchALL的新方法。问题是,它不会起作用。由于这是准备好的声明,语句和SQL在它们达到这一点时还没有准备好。

我对这个过程没有理解做这样的事情,我对我认为发生的事情的猜测已经结束了。

以下是我编辑的代码,它不是由我发起的。我忘记了我得到它的地方 作者是谁,但我不赞成以下代码。我确实从原始版本中更改了一些内容,并取出了与我的问题/问题无关的所有内容。

class my_mysqli_stmt extends mysqli_stmt{

public function __construct($link, $query) {
    parent::__construct($link, $query);
}  

public function fetchAll(){

    echo "FetchAll Method";

    while($this->fetch()){
        # Nothing happens here
        # and don't know what 
        # to insert here if it did  
    }
  }
}


class my_Mysqli extends mysqli {

    public function prepare($query) {
        return new my_Mysqli_stmt($this, $query);
    }
}

具有WHILE语句的此代码块上方的代码块将替换为:

$mysqli->execute();        
$mysqli->store_result();
$mysqli->bind_result($id, $name, $age);     

$mysqli->fetchAll();   <--  This would replace the WHILE loop.

当然这不起作用。也许它并不意味着以这种方式工作,但是如果可以这样做会很好,这样就不需要while循环,所有记录都会通过那一次调用返回。

在代码中看这个似乎也许这个概念在我看来是草率的思考,但是在一个地方封装的所有代码都会很棒。

也许可以这样做:

$mysqli->fetchAll($id, $name, $age); 

并返回绑定参数?我不知道我现在困惑自己。

好的,回头看看..

每当Fetch循环发生时,参数都会使用从数据库中检索到的行中的相关数据自动更新。

这里或者应该发生的事情是,当调用FetchAll时,它返回一个包含所有绑定参数和数据的关联数组,以便在此之后立即返回在MYSQLI_STMT类中创建的数组,然后返回到FetchAll最初是从。来的。

BAM! Presto Chango和检索到的所有记录都在一个关联数组中,随时可以使用。看,所有封装。问题是......怎么样?无法让它发挥作用。

感谢您阅读此问题之墓。

2 个答案:

答案 0 :(得分:0)

我不认为这是可能的(我正在运行PHP 5.4.4),因为无法访问绑定变量。

即使有,也很难隐含地告诉我应该为fetch()

返回的每个值分配哪个绑定变量

我尝试重载bind_result()函数(见下文)但遇到麻烦,因为变量作为参考传递。

public function bind_result() {
    $this->bound_variables = func_get_args();

    // The next line won't work in < 5.3
    call_user_func("parent::bind_result", $this->bound_variables);
}

所以我收到以下错误:Warning: Parameter 1 to mysqli_stmt::bind_result() expected to be a reference, value given...

我还尝试添加fetchAll作为my_Mysqli的一部分而不是my_mysqli_stmt类,但同样,它失败了,因为我们无法将绑定变量作为引用获取,仅作为引用值。

class my_Mysqli extends mysqli {

    public function prepare($query) {
        return new my_Mysqli_stmt($this, $query);
    }

    private $bound_vars;

    public function fetchAll($statement) {

        $args = func_get_args();
        $first = true;
        // Even though we try using 'by reference' here, the arguments themselves
        // are passed in 'by value' by default (because we haven't specified them
        // in the function definition)
        foreach($args as &$a) {
            if ($first) { continue; $first = false; }
            $this->bound_vars[] = $a;
        }

        while($statement->fetch()){
            // This doesn't work, because we haven't got references back to
            // the original variables
            printf ("%s (%s)\n", $this->bound_vars[0], $this->bound_vars[1]);
        }
    }
}
$mysqli = new my_Mysqli();
$stmt = $mysqli->prepare($query);
$stmt->execute();
$stmt->bind_result($id, $age, $name);
$mysqli->fetchAll($stmt, $id, $age, $name);

希望这有助于解释为什么它不起作用!

答案 1 :(得分:0)

这很有可能。
您唯一需要的是切换到 PDO

PDO确实拥有mysqli所需的一切以及更多内容:fetchAll开箱即用,bindValue(!!!),bind-in-executefetchColumn ...

如果您注定要使用mysqli,还有另一种方法:您可以使用手动解析的占位符来模拟预处理语句(就像PDO一样)并获得更强大的代码。这是一个ready made library for this,它更好地支持PDO和mysqli,因为它支持全范围的SQL文字,而不仅仅是有限的部分。