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
为什么行被排除在外的任何想法?
答案 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
,而是使用已实现的Iterator
和ArrayAccess
,以便按预期工作的最终代码(返回所有行)正在使用{{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。