重置PDO结果中的数组指针

时间:2012-02-24 19:59:17

标签: php mysql mysqli

我无法从mysql SELECT方法转移到PDO方法。我想迭代两次获取的数组,两次从第0行开始。在mysql中我会使用:

mysql_data_seek($result,0);

使用PDO方法,我不知道如何完成同样的事情。下面的代码是我试图这样做的方式。第一个while循环工作正常但第二个while循环没有返回任何东西。有人可以告诉我哪里出错了吗?

$pdo = new PDO('mysql:host=' . $host . ';dbname='.$database, $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$stmt = $pdo->prepare('SELECT * FROM mytable WHERE active = 1 ORDER BY name ASC');
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$stmt->execute();

while($row = $stmt->fetch())
{
    //do something starting with row[0]
}
while($row = $stmt->fetch())
{
    //do something else starting with row[0]
}

感谢您的帮助。

7 个答案:

答案 0 :(得分:25)

将结果保存到数组中,然后将该数组循环两次。

$pdo = new PDO('mysql:host=' . $host . ';dbname='.$database, $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$stmt = $pdo->prepare('SELECT * FROM mytable WHERE active = 1 ORDER BY name ASC');
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$stmt->execute();

$rows = $stmt->fetchAll();

foreach ($rows as $r) {
    // first run
}

foreach ($rows as $r) {
    // seconds run
}

答案 1 :(得分:4)

根据php手册,您可以多次发出查询,如果使用PDO :: prepare()准备PDOStatement对象,则可以发出多次调用PDOStatement :: execute()的语句。 所以你的代码看起来就像那样。

$stmt = $pdo->prepare('SELECT * FROM mytable WHERE active = 1 ORDER BY name ASC');
$stmt->setFetchMode(PDO::FETCH_ASSOC);

//First execute
$stmt->execute();
while($row = $stmt->fetch())
{
    //do something starting with row[0]
}

//Second execute
$stmt->execute();
while($row = $stmt->fetch())
{
    //do something else starting with row[0]
}

来源:http://php.net/manual/en/pdo.query.php

答案 2 :(得分:3)

fetch — Fetches the next row from a result set

所以当它退出第一个时它已经到达了resultSet的最后一个元素 这就是为什么第二次没有返回的原因。

使用fetchAll存储所有结果然后通过它们。

答案 3 :(得分:2)

有时存储fetchAll()的结果不是一个选项。相反,您可以在调用fetchAll()之前克隆pdo对象。

$pdo_copy = clone $pdo;

$num_rows = count($pdo_copy->fetchAll());

现在我仍然可以使用pdo对象来执行fetchObject();

之类的语句

答案 4 :(得分:1)

您需要通过在prepare中提供PDO::CURSOR_SCROLL作为选项来告诉声明它必须是可滚动的。然后使用PDO::FETCH_ORI_FIRST在到达结尾后再次访问第一个元素,以便重新开始。

完整代码:

$pdo = new PDO('mysql:host=' . $host . ';dbname='.$database, $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

//Making cursor scrollable
$options = array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL);
$stmt = $pdo->prepare('SELECT * FROM mytable WHERE active = 1 ORDER BY name ASC',
                $options);

$stmt->setFetchMode(PDO::FETCH_ASSOC);
$stmt->execute();

while($row = $stmt->fetch())
{
    //do something starting with row[0]
}

//For the first row we use PDO::FETCH_ORI_FIRST 
//to get the first element again. This will also 
//move the cursor to that element
$first = true; 
while($row = $stmt->fetch(null, $first ? PDO::FETCH_ORI_FIRST : PDO::FETCH_ORI_NEXT)))
{
    $first = false;
    //do something else starting with row[0]
}

答案 5 :(得分:-1)

其他解决方案是,如果您再次在结果queryString上运行查询并获取该信息:

public function fetch_again( $query_result, $fetch_type='fetch' )
{
    return $this->pdo->query($query_result->queryString)->$fetch_type();
}

答案 6 :(得分:-3)

if($stmt->fetchColumn() >= 0)
{
    $stmt->execute(); //Reset cursor
    while($rs = $stmt->fetchObject())
    {
        echo "Data: ".$rs->data;
    }
}
else
{
    echo '0';
}