围绕着许多相互矛盾的陈述。在PHP中使用PDO进行行计数的最佳方法是什么?在使用PDO之前,我只是简单地使用了mysql_num_rows
。
fetchAll
是我不想要的东西,因为我有时可能会处理大型数据集,所以对我的使用不利。
你有什么建议吗?
$sql = "SELECT count(*) FROM `table` WHERE foo = bar";
$result = $con->prepare($sql);
$result->execute();
$number_of_rows = $result->fetchColumn();
不是最优雅的方式,加上它涉及额外的查询。
PDO有PDOStatement::rowCount()
,显然在MySql中不起作用。太痛苦了。
来自PDO Doc:
对于大多数数据库,PDOStatement :: rowCount()不返回受SELECT语句影响的行数。相反,使用PDO :: query()发出带有与预期SELECT语句相同的谓词的SELECT COUNT(*)语句,然后使用PDOStatement :: fetchColumn()来检索将返回的行数。然后,您的应用程序可以执行正确的操作
编辑:上面的代码示例使用一个预准备语句,在许多情况下,可能不需要计算行,所以:
$nRows = $pdo->query('select count(*) from blah')->fetchColumn();
echo $nRows;
当问题是mysql如何使用PHP PDO计算或获取表中的行数时,我使用它
// count total number of rows
$query = "SELECT COUNT(*) as total_rows FROM sometable";
$stmt = $con->prepare($query);
// execute query
$stmt->execute();
// get total rows
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$total_rows = $row['total_rows'];
学分归Mike @ codeofaninja.com所有
看看这个链接:http://php.net/manual/en/pdostatement.rowcount.php不建议在SELECT语句中使用rowCount()!
要在查询中使用变量,您可以使用bindValue()
或bindParam()
要在查询中使用变量,您必须使用bindValue()
或bindParam()
。并且不要将变量与" . $variable . "
连接起来
$statement = "SELECT count(account_id) FROM account
WHERE email = ? AND is_email_confirmed;";
$preparedStatement = $this->postgreSqlHandler->prepare($statement);
$preparedStatement->bindValue(1, $account->getEmail());
$preparedStatement->execute();
$numberRows= $preparedStatement->fetchColumn();
GL
有一个简单的解决方案。如果您使用PDO连接到您的数据库,如下所示:
try {
$handler = new PDO('mysql:host=localhost;dbname=name_of_your_db', 'your_login', 'your_password');
$handler -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $e) {
echo $e->getMessage();
}
然后,对DB的查询将是:
$query = $handler->query("SELECT id FROM your_table WHERE ...");
最后,计算与您的查询匹配的行如下所示
$amountOfRows = $query->rowcount();
这是PDO类的定制扩展,带有辅助函数,用于检索上一个查询的“WHERE”条件所包含的行数。
但是,您可能需要添加更多“处理程序”,具体取决于您使用的命令。现在它只适用于使用“FROM”或“UPDATE”的查询。
class PDO_V extends PDO
{
private $lastQuery = null;
public function query($query)
{
$this->lastQuery = $query;
return parent::query($query);
}
public function getLastQueryRowCount()
{
$lastQuery = $this->lastQuery;
$commandBeforeTableName = null;
if (strpos($lastQuery, 'FROM') !== false)
$commandBeforeTableName = 'FROM';
if (strpos($lastQuery, 'UPDATE') !== false)
$commandBeforeTableName = 'UPDATE';
$after = substr($lastQuery, strpos($lastQuery, $commandBeforeTableName) + (strlen($commandBeforeTableName) + 1));
$table = substr($after, 0, strpos($after, ' '));
$wherePart = substr($lastQuery, strpos($lastQuery, 'WHERE'));
$result = parent::query("SELECT COUNT(*) FROM $table " . $wherePart);
if ($result == null)
return 0;
return $result->fetchColumn();
}
}
返回第一个条目的快速一个班轮。这对于非常基本的查询很有用。
<?php
$count = current($db->query("select count(*) from table")->fetch());
?>
我尝试使用Oracle 11.2的$count = $stmt->rowCount();
,但它没有用。我决定使用for循环,如下所示。
$count = "";
$stmt = $conn->prepare($sql);
$stmt->execute();
echo "<table border='1'>\n";
while($row = $stmt->fetch(PDO::FETCH_OBJ)) {
$count++;
echo "<tr>\n";
foreach ($row as $item) {
echo "<td class='td2'>".($item !== null ? htmlentities($item, ENT_QUOTES):" ")."</td>\n";
} //foreach ends
}// while ends
echo "</table>\n";
//echo " no of rows : ". oci_num_rows($stmt);
//equivalent in pdo::prepare statement
echo "no.of rows :".$count;
对于我想要特定行的直接查询,并想知道它是否被找到,我使用类似的东西:
function fetchSpecificRow(&$myRecord) {
$myRecord = array();
$myQuery = "some sql...";
$stmt = $this->prepare($myQuery);
$stmt->execute(array($parm1, $parm2, ...));
if ($myRecord = $stmt->fetch(PDO::FETCH_ASSOC)) return 0;
return $myErrNum;
}
当你在你的mysql语句中创建一个COUNT(*)时
$q = $db->query("SELECT COUNT(*) FROM ...");
你的mysql查询已经计算了为什么在php再次计数的结果数?得到你的mysql的结果
$q = $db->query("SELECT COUNT(*) as counted FROM ...");
$nb = $q->fetch(PDO::FETCH_OBJ);
$nb = $nb->counted;
和$nb
将包含你用mysql语句计算的整数有点长写,但执行速度快
编辑:抱歉错误的帖子,但是作为一些示例显示查询与count in,我建议使用mysql结果,但如果你不使用sql中的count fetchAll()是有效的,如果你将结果保存在变量中你不会松开一条线。
$data = $dbh->query("SELECT * FROM ...");
$table = $data->fetchAll(PDO::FETCH_OBJ);
count($table)
将返回行数,你仍然可以使用像$row = $table[0]
或使用foreach
后的结果
foreach($table as $row){
print $row->id;
}
您可以将最佳方法组合到一行或函数中,并为您自动生成新查询:
function getRowCount($q){
global $db;
return $db->query(preg_replace('/SELECT [A-Za-z,]+ FROM /i','SELECT count(*) FROM ',$q))->fetchColumn();
}
$numRows = getRowCount($query);
正如我之前在an answer to a similar question中写的那样,mysql_num_rows()
工作的唯一原因是因为它在内部提取所有行以提供信息,即使它看起来不像你。
所以在PDO中,您的选择是:
FOUND_ROWS()
函数。fetchAll()
函数将所有行提取到数组中,然后在其上使用count()
。SELECT COUNT(*)
做一个额外的查询。<table>
<thead>
<tr>
<th>Sn.</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<?php
$i=0;
$statement = $db->prepare("SELECT * FROM tbl_user ORDER BY name ASC");
$statement->execute();
$result = $statement->fetchColumn();
foreach($result as $row) {
$i++;
?>
<tr>
<td><?php echo $i; ?></td>
<td><?php echo $row['name']; ?></td>
</tr>
<?php
}
?>
</tbody>
</table>
function count_x($connect) {
$query = " SELECT * FROM tbl WHERE id = '0' ";
$statement = $connect->prepare($query); $statement->execute();
$total_rows = $statement->rowCount();
return $total_rows;
}
使用参数array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL)
,否则显示-1:
使用array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL)
参数,不使用-1
例:
$res1 = $mdb2->prepare("SELECT clave FROM $tb WHERE id_usuario='$username' AND activo=1 and id_tipo_usuario='4'", array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$res1->execute();
$count=$res1->rowCount();
echo $count;
在使用PDO之前,我只是简单地使用了
mysql_num_rows()
。
你不应该首先使用它。
mysql_num_rows()
以及PDOStatement::rowCount()
暗示您已经选择了您的数据。在这种情况下,这种功能只有两种可能的用例:
前者永远不应该被使用。永远不应该选择行来计算它们,因为您的服务器确实可能因为返回大数据集而窒息。
此外,仅选择行来计算它们是没有意义的。必须运行count(*)
查询,只返回一行。
第二个用例不是灾难性的,而是毫无意义的:如果你需要知道你的查询是否返回了任何数据,你总是拥有数据本身!
比如,如果您只选择一行,则只需获取它,然后检查结果:
$stmt->execute();
$row = $stmt->fetch();
if ($row) { // here! as simple as that
}
如果你需要获得很多行,那么你可以使用fetchAll()
。
fetchAll()
是我不想要的东西,因为我有时可能会处理大型数据集
请注意,在Web应用程序中,您不应该选择大量的行。只应选择将在网页上实际使用的行。为此,必须使用SQL中的LIMIT
或类似子句。对于如此适量的数据,使用fetchAll()
是可以的
在极少数情况下,当您需要选择真正的大量行(例如在控制台应用程序中)时,为了减少使用的内存量,您必须使用unbuffered query, but in this case rowCount()
won't be available anyway,因此此功能也没有用处。
所以你看,rowCount()
既没有用例也没有用于替换它的额外查询,如接受的答案所示。
这是超级晚了,但我遇到了问题,我这样做:
function countAll($table){
$dbh = dbConnect();
$sql = "select * from `$table`";
$stmt = $dbh->prepare($sql);
try { $stmt->execute();}
catch(PDOException $e){echo $e->getMessage();}
return $stmt->rowCount();
它非常简单,容易。 :)
我最终使用了这个:
$result = $db->query($query)->fetchAll();
if (count($result) > 0) {
foreach ($result as $row) {
echo $row['blah'] . '<br />';
}
} else {
echo "<p>Nothing matched your query.</p>";
}
这篇文章很老但是用PDO在php中获取行计数很简单
$stmt = $db->query('SELECT * FROM table');
$row_count = $stmt->rowCount();
这是一个老帖子,但在寻找替代方案时感到沮丧。非常不幸的是,PDO缺乏此功能,特别是因为PHP和MySQL倾向于齐头并进。
使用fetchColumn()存在一个令人遗憾的缺陷,因为fetchColumn()会将指针移动到下一行,因此无法再使用该结果集(有效)。例如,如果您有类似的结果
如果使用fetchColumn(),你会发现返回了3个水果,但如果你现在循环结果,你只有两列,fetchColumn()的价格是第一列结果的丢失输出了多少行。这导致了草率编码,并且如果实施则完全错误的结果。
所以现在,使用fetchColumn()你必须实现全新的调用和MySQL查询才能得到一个新的工作结果集。 (我希望,自上次查询以来没有改变),但不太可能,但它可能会发生。此外,所有行计数验证的双查询开销。对于这个例子来说这个很小,但是在一个连接的查询中解析了200万行,而不是一个令人愉快的代价。
我喜欢PHP并且每天都使用PHP来支持参与其开发以及整个社区的每个人,但是真的希望在将来的版本中解决这个问题。对于PHP PDO来说,这是'我'唯一的抱怨,否则这是一个很棒的课程。
回答这个问题是因为我现在已经知道了这一点并且可能会有用。
请记住,您无法两次获取结果。您必须将获取结果保存到数组中,通过count($array)
获取行计数,并使用foreach
输出结果。例如:
$query = "your_query_here";
$STH = $DBH->prepare($query);
$STH->execute();
$rows = $STH->fetchAll();
//all your results is in $rows array
$STH->setFetchMode(PDO::FETCH_ASSOC);
if (count($rows) > 0) {
foreach ($rows as $row) {
//output your rows
}
}
如果你只想获得行数(不是数据),即。在预准备语句中使用COUNT(*),然后您需要做的就是检索结果并读取值:
$sql = "SELECT count(*) FROM `table` WHERE foo = bar";
$statement = $con->prepare($sql);
$statement->execute();
$count = $statement->fetch(PDO::FETCH_NUM); // Return array indexed by column number
return reset($count); // Resets array cursor and returns first value (the count)
实际上检索所有行(数据)以执行简单计数是浪费资源。如果结果集很大,您的服务器可能会阻塞它。