克隆 PHP PDO 记录集对象以计算 select 语句返回的行数

发布于 2024-10-13 16:44:51 字数 673 浏览 3 评论 0原文

我正在重构使用 adodb 作为数据库库的 PHP 应用程序的一部分,以便开始使用 PDO。

我需要一些可以为我提供选择记录集中包含的行数的东西,可以轻松替换我之前使用的旧 $rs->RecordCount() adodb 方法。它应该适用于 sqlite3。

我不能简单地重新执行查询(或使用 select count(*) 重新执行查询),因为我无法对原始应用程序进行太多更改,应用程序在许多部分进行调用一个函数 get_num_rows($rs) (仅包含 $rs->RecordCount() ),我可以更改该函数的内容。

我尝试克隆记录集对象并计算获取的记录:

function get_num_rows($rs)
{
    $rs_copy = clone $rs;
    return (count($rs_copy->fetchAll()));
}

但它不起作用,因为 $rs_copy->fetchAll() 返回我 false。我无法在原始记录集上执行此操作,因为稍后在应用程序中我需要再次获取它,并且我认为 PDO sqlite 中无法重用记录集(如果我错了,请纠正我)。

你有什么解决办法吗?

I'm refactoring part of a PHP application which uses adodb as db library, in order to start using PDO.

I need something which provides me the number of rows included in a select recordset, something that can easily replace the old $rs->RecordCount() adodb method that I used before. It should work for sqlite3.

I can't simply re-execute the query (or re-execute the query using a select count(*) ) because I can't change so much the original application, the application calls in many parts a function get_num_rows($rs) (which contains just $rs->RecordCount() ) and I can just change the content of that function.

I tried cloning the recordset object and counting the records fetched:

function get_num_rows($rs)
{
    $rs_copy = clone $rs;
    return (count($rs_copy->fetchAll()));
}

but it doesn't work, because $rs_copy->fetchAll() returns me false. I can't do it on the original recordset because later in the applicaiton I need to fetch it again and I think there is no way in PDO sqlite to reuse the recordset (correct me if I'm wrong).

Do you have any solutions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

混吃等死 2024-10-20 16:44:51

在主查询中使用 LIMIT 时,建议使用 SELECT COUNT(*) FROM 作为第二个查询运行来计算结果集中的行数。它不会两次获取相同的数据,它只是计算找到的行数并返回 1 行(一个整数)。使用 LIMIT 语句查找行数的另一种方法是在第一个查询中使用 SELECT SQL_CALC_FOUND_ROWS (field list) FROM ...,然后运行 ​​SELECT FOUND_ROWS() 来获取行数,但是,此方法比前面提到的方法慢。请注意,在 PHP 中运行 count() 只会提供返回的行数,而不是数据库中找到的实际行数(如果您使用 LIMIT )。

干杯

Using SELECT COUNT(*) FROM run as a second query is the recommended way to count the number of rows in a result set when using LIMIT in your primary query. It won't fetch the same data twice, it simply counts how many rows are found and returns 1 row, an integer. Another way to find the number of rows when using the LIMIT statement is to use SELECT SQL_CALC_FOUND_ROWS (field list) FROM ... in your first query, then run SELECT FOUND_ROWS() to get the number of rows, however, this method is slower than the previous one mentioned. Be aware that running count() in PHP will only give you the number of rows returned, not the actual number of rows found in the database (if you're using LIMIT).

Cheers

土豪 2024-10-20 16:44:51

也许一种可能性是像 col shrapnel 建议的那样,并将结果存储在数组中。您可以通过扩展 PDOStatement 然后

http://www 来保持界面干净.php.net/manual/en/pdo.setattribute.php
PDO::ATTR_STATEMENT_CLASS

所以它会返回你 EugenioEnhancedPDOStatement

Maybe a possibility is to do like col shrapnel suggested and store the result in an array. You might be able to keep the interface clean by extending PDOStatement and then

http://www.php.net/manual/en/pdo.setattribute.php
PDO::ATTR_STATEMENT_CLASS

So it will return you EugenioEnhancedPDOStatement

緦唸λ蓇 2024-10-20 16:44:51

感谢大家。
我找到了一个更简单、快速但肮脏的解决方案,我的新 get_num_rows() 将类似于:

$temp_ar = explode("FROM", $rs->queryString);

$sql = "SELECT COUNT(*) FROM ".$temp_ar[1];

$conn->query($sql);

...

Thanks to all.
I have found an easier, quick and dirty solution, my new get_num_rows() will be something like:

$temp_ar = explode("FROM", $rs->queryString);

$sql = "SELECT COUNT(*) FROM ".$temp_ar[1];

$conn->query($sql);

...
暮倦 2024-10-20 16:44:51

您无法正确克隆和/或序列化/反序列化 PDO 对象,很可能是因为它们与连接资源紧密相关。

事实是,克隆它是没有意义的。如果 $rs 是 PDOStatement 对象,您可以重新执行它,因为您有权访问它。这是准备好的语句的主要优点之一,准备一次,执行多次

像这样:

function get_num_rows($rs)
{
 $rs->execute();
 return (count($rs->fetchAll()));
}

您猜对了:在同一个 PDOStatement 实例上第二次调用execute()而不指定任何参数将重用最后一组参数并按原样重新执行语句。< /strong>

因此,不需要克隆 PDOStatement 对象。

You can't properly clone and/or serialize/unserialize PDO objects, most probably because they are tightly tied to a connection resource.

The fact is, there is no point cloning it. If $rs is a PDOStatement object, you can just re-execute it, since you have access to it. This is one of the main advantage of prepared statements, prepare once, execute multiple times.

Like this:

function get_num_rows($rs)
{
 $rs->execute();
 return (count($rs->fetchAll()));
}

You guessed it: calling execute() on the same PDOStatement instance the second time without specifying any parameters will reuse the last set of parameters and re-execute the statement as is.

Therefore, there is no need to clone PDOStatement objects.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文