【问题标题】:Extend mysqli_stmt add fetchAll for 5.2.17?为 5.2.17 扩展 mysqli_stmt 添加 fetchAll?
【发布时间】:2012-11-14 10:11:46
【问题描述】:

php 5.2.17

mysqliprepared statements 结果绑定到变量。

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

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

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

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

我不明白这是如何工作的,我对 OOP 和扩展核心 php 类有点陌生,希望能得到尽可能多的解释,以便我学习。

我的虚拟主机有 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最初是从那里调用的。

砰! Presto Chango 和所有检索到的记录都在一个关联数组中,可供使用。看,全部封装。问题是.. 怎么样?无法让它工作。

感谢您阅读这个问题的坟墓。

【问题讨论】:

  • 玩这个更多我能够在 mysqli_stmt 类中的 while 循环内检索记录,但 while 循环遍历所有记录,绑定变量仅显示最后一条记录。无法将以前的记录存储在数组中。所以我停止搞砸这个并决定将我的循环留在原处。如果你想玩它,看看你能不能让它工作,请发布你的解决方案。

标签: php mysql mysqli


【解决方案1】:

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

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

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

【讨论】:

  • 这是关于 MYSQLI 而不是 PDO。感谢您的意见。
【解决方案2】:

我认为这是不可能的(我正在运行 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);

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

【讨论】:

  • 你的 5.4 很可能会用 mysqlnd 编译,因此get_result 将使这件事成为可能。
  • 是的,我想通并理解为什么这不起作用。我能够进一步深入研究并提出“足够好”的解决方案。有了进行自定义处理的好处,所以我不必在其他地方处理它。它还使事情变得更容易,并且我的脚本中需要的代码更少。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-28
  • 2021-08-31
  • 1970-01-01
  • 1970-01-01
  • 2016-04-14
相关资源
最近更新 更多