A classe PDOStatement

(PHP 5 >= 5.1.0, PHP 7, PHP 8, PECL pdo >= 1.0.0)

Introdução

Representa uma instrução preparada e, após a execução da instrução, um conjunto de resultados associado.

Resumo da classe

class PDOStatement implements IteratorAggregate {
/* Propriedades */
/* Métodos */
public bindColumn(
    string|int $column,
    mixed &$var,
    int $type = PDO::PARAM_STR,
    int $maxLength = 0,
    mixed $driverOptions = null
): bool
public bindParam(
    string|int $param,
    mixed &$var,
    int $type = PDO::PARAM_STR,
    int $maxLength = 0,
    mixed $driverOptions = null
): bool
public bindValue(string|int $param, mixed $value, int $type = PDO::PARAM_STR): bool
public closeCursor(): bool
public columnCount(): int
public errorCode(): ?string
public errorInfo(): array
public execute(?array $params = null): bool
public fetch(int $mode = PDO::FETCH_DEFAULT, int $cursorOrientation = PDO::FETCH_ORI_NEXT, int $cursorOffset = 0): mixed
public fetchAll(int $mode = PDO::FETCH_DEFAULT): array
public fetchAll(int $mode = PDO::FETCH_COLUMN, int $column): array
public fetchAll(int $mode = PDO::FETCH_CLASS, string $class, ?array $constructorArgs): array
public fetchAll(int $mode = PDO::FETCH_FUNC, callable $callback): array
public fetchColumn(int $column = 0): mixed
public fetchObject(?string $class = "stdClass", array $constructorArgs = []): object|false
public getAttribute(int $name): mixed
public getColumnMeta(int $column): array|false
public nextRowset(): bool
public rowCount(): int
public setAttribute(int $attribute, mixed $value): bool
public setFetchMode(int $mode): bool
public setFetchMode(int $mode = PDO::FETCH_COLUMN, int $colno): bool
public setFetchMode(int $mode = PDO::FETCH_CLASS, string $class, ?array $constructorArgs = null): bool
public setFetchMode(int $mode = PDO::FETCH_INTO, object $object): bool
}

Propriedades

queryString

String de consulta usada.

Registro de Alterações

Versão Descrição
8.0.0 PDOStatement agora implementa IteratorAggregate em vez de Traversable.

Índice

add a note add a note

User Contributed Notes 7 notes

up
17
Gino D.
6 years ago
I don't know why PDOStatement don't return "execution time" and "found rows" so here I created an extended class of PDOStatement with these attributes.

Just have to "setAttribute" of PDO's object to $PDO->setAttribute(\PDO::ATTR_STATEMENT_CLASS , ['\customs\PDOStatement', [&$this]]);

<?php

/**
*
*
*
*/

namespace customs;

/**
*
*
*
*/

final class PDOStatement extends \PDOStatement {

   
/**
    *
    *
    *
    */

   
protected $PDO = null;
    protected
$inputParams = [];
    protected
$executionTime = 0;
    protected
$resultCount = 0;

   
/**
    *
    *
    *
    */

   
protected function __construct(PDO &$PDO) {
       
$this->PDO = $PDO;
       
$this->executionTime = microtime(true);
    }

   
/**
    *
    *
    *
    */

   
final public function getExecutionError(int $i = 2) {
       
$executionError = $this->errorInfo();

        if (isset(
$executionError[$i]))
            return
$executionError[$i];

        return
$executionError;
    }

   
/**
    *
    *
    *
    */

   
final public function getExecutionTime($numberFormat = false, $decPoint = '.', $thousandsSep = ',') {
        if (
is_numeric($numberFormat))
            return
number_format($this->executionTime, $numberFormat, $decPoint, $thousandsSep);
       
        return
$this->executionTime;
    }

   
/**
    *
    *
    *
    */

   
final public function getResultCount($numberFormat = false, $decPoint = '.', $thousandsSep = ',') {
        if (
is_numeric($numberFormat))
            return
number_format($this->resultCount, $numberFormat, $decPoint, $thousandsSep);
       
        return
$this->resultCount;
    }

   
/**
    *
    *
    *
    */

   
final public function getLastInsertId() {
        return
$this->PDO->lastInsertId();
    }

   
/**
    *
    *
    *
    */

   
final public function bindValues(array $inputParams) {
        foreach (
$this->inputParams = array_values($inputParams) as $i => $value) {
           
$varType = is_null($value) ? \PDO::PARAM_NULL : is_bool($value) ? \PDO::PARAM_BOOL : is_int($value) ? \PDO::PARAM_INT : \PDO::PARAM_STR;

            if (!
$this->bindValue(++ $i, $value, $varType))
                return
false;
        }

        return
true;
    }

   
/**
    *
    *
    *
    */

   
final public function execute($inputParams = null) {
        if (
$inputParams)
           
$this->inputParams = $inputParams;

        if (
$executed = parent::execute($inputParams))
           
$this->executionTime = microtime(true) - $this->executionTime;

        return
$executed;
    }

   
/**
    *
    *
    *
    */

   
final public function fetchAll($how = null, $className = null, $ctorArgs = null) {
       
$resultSet = parent::fetchAll(... func_get_args());

        if (!empty(
$resultSet)) {
           
$queryString = $this->queryString;
           
$inputParams = $this->inputParams;

            if (
preg_match('/(.*)?LIMIT/is', $queryString, $match))
               
$queryString = $match[1];

           
$queryString = sprintf('SELECT COUNT(*) AS T FROM (%s) DT', $queryString);

            if ((
$placeholders = substr_count($queryString, '?')) < count($inputParams))
               
$inputParams = array_slice($inputParams, 0, $placeholders);

            if ((
$sth = $this->PDO->prepare($queryString)) && $sth->bindValues($inputParams) && $sth->execute())
               
$this->resultCount = $sth->fetchColumn();
               
           
$sth = null;
        }

        return
$resultSet;
    }
}
?>
up
0
nmurzin at mail dot ru
3 years ago
I think I found a way to execute a protected SQL query and at the same time find out the number of affected records.
I have the table 'tbl_users' with the following fields: id, login, password, age

<?
const DB_DRIVER = "mysql";
const DB_HOST = "localhost";
const DB_NAME = "my_db_name";
const DB_LOGIN = "root";
const DB_PASS = "root"; //OpenServer.

$connectionString = DB_DRIVER.':host='.DB_HOST.';dbname='.DB_NAME;
try
{
    //Connect to database.
    $db = new PDO($connectionString, DB_LOGIN, DB_PASS);
}
catch(PDOException $e)
{
    die("Error: ".$e->getMessage());
}
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

try
{
   
    //Decreasing age for user 'nick1'.
    $prep1 = $db->prepare("UPDATE tbl_users SET age=age-1 WHERE login='nick1'");

    //Increasing age for user 'nick2'.
    $prep2 = $db->prepare("UPDATE tbl_users SET \r\n age=age+1 WHERE login='nick2'");

    //Start transaction.
    $db->beginTransaction(); //Table type must be InnerDB!

    //We assume that everything will be fine.
    $flagDone = true;

    //The exec() method returns the number of rows affected by the query.
    //$prep1->queryString is already an escaped SQL string.
    $result = $db->exec($prep1->queryString);
    if($result==false || $result!=1) //var_dump($result) - int(1) or bool(false).
        $flagDone = false;

    $result = $db->exec($prep2->queryString);
    if($result==false || $result!=1)
        $flagDone = false;

    if($flagDone)
    {
        if($db->commit())
            echo "Transaction was successful";
    }       
    else{
            echo "Transaction fail";
            $db->rollback();
    }
    echo "<br>";

}
catch(PDOException $e)
{
    die("Error: ".$e->getMessage());
}
up
-2
luis-m-cardoso at ext dot ptinovacao dot pt
10 years ago
Solved ;)

<?php

$host
= "yourHost";
$user = "yourUser";
$pass = "yourPass";
$db = "yourDB";

$cursor = "cr_123456";

try
{
 
$dbh = new PDO("pgsql:host=$host;port=5432;dbname=$db;user=$user;password=$pass");
  echo
"Connected<p>";
}
catch (
Exception $e)
{
  echo
"Unable to connect: " . $e->getMessage() ."<p>";
}

$dbh->beginTransaction();

$query = "SELECT yourFunction(0::smallint,'2013-08-01 00:00','2013-09-01 00:00',1::smallint,'$cursor')";

$dbh->query($query);

$query = "FETCH ALL IN \"$cursor\"";

echo
"begin data<p>";

foreach (
$dbh->query($query) as $row)
{
    echo
"$row[0] $row[1] $row[2] <br>";
}

echo
"end data";

?>
up
-2
Example
5 years ago
1.- Conectar a la base de datos usando try/catch.
$pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $user, $pass");

2.- Preparar la consulta (insert,update,delete).
2.1.- Preparar la consulta:
    $stmt = $pdo->prepare("INSERT INTO alumnos( nombre, apellidos) values ( 'Taylor','Swift' )");
    $stmt = $pdo->prepare("INSERT INTO colegas (name, addr, city) values (?, ?, ?)");
    $stmt = $pdo->prepare("INSERT INTO colegas (name, addr, city) value (:name, :addr, :city)");

2.2.- Asignar parámetros en la consulta:
    $stmt->bindParam(':name', $name);
    $name='Pepito';

    $datos = array('Cathy', '9 Dark and Twisty Road', 'Cardiff');
    $stmt = $pdo->prepare("INSERT INTO colegas (name, addr, city) values (?, ?, ?)");

    $datos = array( 'name' => 'Cathy', 'addr' => '9 Dark and Twisty', 'city' => 'Cardiff' );
    $stmt = $pdo->prepare("INSERT INTO colegas (name, addr, city) value (:name, :addr, :city)");

2.3.- Ejecutar la consulta
try{
    $stmt->execute();

        // o bien
    $stmt->execute($datos);
}
catch(PDOException $err)
{
   // Mostramos un mensaje genérico de error.
   echo "Error: ejecutando consulta SQL.";
}

2.- Preparar la consulta (select).
2.1.- Preparar la consulta:
try{
       // ATENCION: si no tenemos parámetros en la consulta, la podemos ejecutar con ->query (recomendable en SELECT) o con ->exec (para INSERT, UDPATE, DELETE)
    $stmt = $pdo->query('SELECT name, addr, city from colegas');
}
catch(PDOException $err)
{
   // Mostramos un mensaje genérico de error.
   echo "Error: ejecutando consulta SQL.";
}

$stmt = $pdo->prepare('SELECT name, addr, city from colegas where city =:ciudad'); (con parámetros)
$datos = array( ':ciudad' => 'Santiago');

try{
    $stmt->execute($datos);
}
catch(PDOException $err)
{
   // Mostramos un mensaje genérico de error.
   echo "Error: ejecutando consulta SQL.";
}

2.2.- Leemos los datos del recordset (conjunto de registros) que nos devuelve SELECT en el objeto PDOStatement.

2.2.1.- Se puede leer cada fila del recordset con ->fetch() del objeto PDOStatement o mediante ->fetchAll() (obtiene todas las filas del recordset).
'''Este bloque de código lo ejecutaremos dentro de la sección try { ..... }'''

    while($row = $stmt->fetch()) {
        echo $row['name'] . "<br/>";
        echo $row['addr'] . "<br/>";
        echo $row['city'] . "<br/>";
    }

    $row = $sql->fetchAll();
    foreach($data as $row)
        $id = $row['id'];
        $content = $row['content'];
    }

3.- Cerrar la conexión.
    // Liberamos los recursos utilizados por el recordset $stmt
    $stmt=null;

    // Se recomienda cerrar la conexión para liberar recursos de forma más rápida.
    $pdo = null;
up
-10
code4fun at gmail dot com
5 years ago
Example of persist in bd

public function persist($dbh) {
        if ($this->id) {//Update
            $modificar = 'UPDATE usuarios set nombre = :nombre ,pass = :pass'
                    . '    WHERE id = :id';
            $persistir = $dbh->prepare($modificar);
            $persistido = $persistir->execute(array(':nombre' => $this->getNombre(), ':pass' => $this->getPass(), ':id' => $this->getId()));
        } else {
            $insert = 'INSERT INTO usuarios (nombre,pass) VALUES (:nombre,:pass)';
            $persistir = $dbh->prepare($insert);
            $persistido = $persistir->execute(array('nombre' => $this->getNombre(), 'pass' => $this->getPass()));
            if ($persistido) {
                $this->setId($dbh->lastInsertId());
            } else {
                throw new Exception;
            }
        }
        return $persistido;
    }

//Example of select
   
    public function getCredencial($dbh) {
        $select = "SELECT * FROM usuarios WHERE nombre= :user AND pass= :pass";
        $consulta = $dbh->prepare($select);
        $consulta->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, "Usuario");
        $consulta->execute(array(":user" => $this->nombre, ":pass" => $this->pass));
        $logueado = $consulta->fetch();
        return $logueado;
    }

//Example of select all
public static function getAll($bd, $id) {
        $query = 'SELECT * FROM `cuentas` WHERE idUsuario = :idUsuario';
        $prepare = $bd->prepare($query);
        $prepare->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'Movimiento');
        $prepare->execute(array(':idUsuario' => $id));
        $movimientos = $prepare->fetchAll();
        return $movimientos;
    }

//Example of delete

public function eliminar($dbh,$id) {
        $sql = 'DELETE FROM alumnos '
                . 'WHERE id = :id';
        $stmt = $dbh->prepare($sql);
        $stmt->bindValue(':id', $id);

        $stmt->execute();

        return $stmt->rowCount();
    }
up
-10
code4fun at gmail dot com
5 years ago
Example of persist in bd

public function persist($dbh) {
        if ($this->id) {//Update
            $modificar = 'UPDATE usuarios set nombre = :nombre ,pass = :pass'
                    . '    WHERE id = :id';
            $persistir = $dbh->prepare($modificar);
            $persistido = $persistir->execute(array(':nombre' => $this->getNombre(), ':pass' => $this->getPass(), ':id' => $this->getId()));
        } else {
            $insert = 'INSERT INTO usuarios (nombre,pass) VALUES (:nombre,:pass)';
            $persistir = $dbh->prepare($insert);
            $persistido = $persistir->execute(array('nombre' => $this->getNombre(), 'pass' => $this->getPass()));
            if ($persistido) {
                $this->setId($dbh->lastInsertId());
            } else {
                throw new Exception;
            }
        }
        return $persistido;
    }

//Example of select
   
    public function getCredencial($dbh) {
        $select = "SELECT * FROM usuarios WHERE nombre= :user AND pass= :pass";
        $consulta = $dbh->prepare($select);
        $consulta->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, "Usuario");
        $consulta->execute(array(":user" => $this->nombre, ":pass" => $this->pass));
        $logueado = $consulta->fetch();
        return $logueado;
    }

//Example of select all
public static function getAll($bd, $id) {
        $query = 'SELECT * FROM `cuentas` WHERE idUsuario = :idUsuario';
        $prepare = $bd->prepare($query);
        $prepare->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'Movimiento');
        $prepare->execute(array(':idUsuario' => $id));
        $movimientos = $prepare->fetchAll();
        return $movimientos;
    }

//Example of delete

public function eliminar($dbh,$id) {
        $sql = 'DELETE FROM alumnos '
                . 'WHERE id = :id';
        $stmt = $dbh->prepare($sql);
        $stmt->bindValue(':id', $id);

        $stmt->execute();

        return $stmt->rowCount();
    }
up
-64
rosko at zeta dot org dot au
14 years ago
There are many references around for returning a refcursor from a pgSQL function using pg_query. All essentially boil down to executing the following single statement (or some variation of it):

begin; select yourFunction(params...); fetch all in cursorname; commit;

In PDO, this doesn't work because PDO won't allow multiple statements submitted as a single statement (due to SQL injection detection). Instead, try this or similar:

<?php
$sql
= 'select yourFunction(params...)';
$db = new PDO('pgsql:dbname=yourDBname');
$db->beginTransaction();
$cmd = $db->prepare($sql);
if (
$cmd->execute()) {
  if (
$query = $db->query('fetch all in cursorname')) {
    ...
processing...
   
$query->closeCursor();
   
$cmd->closeCursor();
  }
}
$db->commit();
?>
To Top