PHP的PDO循环返回全部排除第一行

时间:2011-03-13 15:21:08

标签: php symfony1 pdo

symfony (v1.4.6)下的PDOStatement->fetch出现问题,因为始终排除从语句第一行提取记录。

代码如下:

<?php var_dump($stats->rowCount()); ?>
<?php var_dump(count($stats->fetchAll())); ?>

产地:

int 14
int 13

代码如下:

<?php $i = 0; ?>
<?php var_dump($stats->rowCount()); ?>
<?php while ($v = $stats->fetch()): ?>
    <?php var_dump(++$i); ?>

产地:

int 14
int 1
int 2
int 3
int 4
int 5
int 6
int 7
int 8
int 9
int 10
int 11
int 12
int 13

为什么行被排除在外的任何想法?

4 个答案:

答案 0 :(得分:4)

引用PDOStatement->rowCount的文档:

  

如果执行的最后一条SQL语句   相关的PDOStatement是一个   SELECT语句,有些数据库可能   返回返回的行数   那句话。
但是,这个   所有人都无法保证行为   数据库和不应该被依赖   用于便携式应用程序。

以及关于示例#2的说明:

  

对于大多数数据库,   PDOStatement::rowCount()没有   返回受影响的行数   一个SELECT声明。
相反,   使用PDO::query()发出SELECT COUNT(*)语句   谓词是您的预期SELECT   声明,然后使用   PDOStatement::fetchColumn()来   检索将要的行数   被退回你的申请可以   然后执行正确的操作。

所以,并非真正回答为什么你的问题,但我会说你不应该使用rowCount()进行select查询; - )


另见该文档页面上的注释;例如,this one,其中包含(引用)

  

看来rowCount的行为是   Mysql 5.0与5.1不同。

并且,查询就像"SELECT 1"一样简单:

  

Mysql 5.0.45,PHP 5.2.5返回1   
Mysql 5.1.30,PHP 5.1.6返回0

答案 1 :(得分:2)

问题已解决并且它与PDO无关,但与Symfony相关的问题(我认为其中一个OutputDecorators但还不确定)

PDOStatement是有效的,当在控制器内部使用->fetch循环时,一切都很好(检索到14条记录)。移动相同的代码后,查看第一条记录总是被排除在结果之外(我认为它与输出装饰器相关的是使用Iterator和ArrayAccess)。

此问题的快速解决方法是不使用while loop,而是使用已实现的IteratorArrayAccess,以便按预期工作的最终代码(返回所有行)正在使用{{1} }

foreach

<?php foreach ($stats as $v): ?> <?php //do stuff with record ?> <?php endforeach; ?> + while循环

->fetch()

答案 2 :(得分:1)

我也有同样的问题,解决这个问题的一种方法是fetchAll()并迭代数组。在我的情况下,这引起了第二个问题:迭代超过10.000条记录会导致内存错误。

在深入研究Symfony后,我发现可以直接设置变量(在动作方法中使用$this->setVar)。 setVar有3个参数:视图中的变量名称,实际数据以及数据是否安全(比它将被转义)。当数据不安全/转义时,所有记录都在mysql语句中。允许你使用fetch循环遍历行。

答案 3 :(得分:1)

我遇到了同样的问题(第一行在迭代行时没有出现),但这是我自己的错。

在我的模板中,我有:

<?php if(!$statement_iter->fetch()): ?>
...
<?php endif; ?>
<?php foreach($statement_iter as $row): ?>
...
<?php endforeach; ?>

当PDOStatement有任何行时,foreach循环将始终排除第一行。

显然(我现在意识到),if语句调用fetch(),它会将光标向前移动一个。所以,if语句吃掉了第一行! DERP。