PHP Conference Japan 2024

PDOStatement 類別

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

簡介

表示一個預備語句,並且在語句執行後,表示一個相關聯的結果集。

類別概要

類別 PDOStatement 實作 IteratorAggregate {
/* 屬性 */
/* 方法 */
公開 bindColumn(
    字串|整數 $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)
公開 bindValue(字串或整數 (string|int) $param, 混合型別 (mixed) $value, 整數 (int) $type = PDO::PARAM_STR): 布林值 (bool)
公開 closeCursor(): 布林值 (bool)
公開 columnCount(): 整數 (int)
公開 debugDumpParams(): 可為空值的布林值 (?bool)
公開 errorCode(): 可為空值的字串 (?string)
公開 errorInfo(): 陣列 (array)
公開 execute(可為空值的陣列 (?array) $params = null): 布林值 (bool)
公開 fetch(整數 (int) $mode = PDO::FETCH_DEFAULT, 整數 (int) $cursorOrientation = PDO::FETCH_ORI_NEXT, 整數 (int) $cursorOffset = 0): 混合型別 (mixed)
公開 fetchAll(整數 (int) $mode = PDO::FETCH_DEFAULT): 陣列 (array)
公開 fetchAll(int $mode = PDO::FETCH_COLUMN, int $column): array
公開 fetchAll(int $mode = PDO::FETCH_CLASS, string $class, ?array $constructorArgs): array
公開 fetchAll(int $mode = PDO::FETCH_FUNC, callable $callback): array
公開 fetchColumn(int $column = 0): 混合類型
公開 fetchObject(?string $class = "stdClass", array $constructorArgs = []): 物件|false
公開 getColumnMeta(int $column): 陣列|false
公開 rowCount(): int
公開 setAttribute(int $attribute, 混合類型 $value): 布林值
公開 setFetchMode(int $mode): 布林值
公開 setFetchMode(int $mode = PDO::FETCH_COLUMN, int $colno): bool
公開 setFetchMode(int $mode = PDO::FETCH_CLASS, string $class, ?array $constructorArgs = null): bool
公開 setFetchMode(int $mode = PDO::FETCH_INTO, object $object): bool
}

屬性

queryString

使用的查詢字串。

更新日誌

版本 說明
8.0.0 PDOStatement 現在實作 IteratorAggregate 而不是 Traversable

目錄

新增筆記

使用者貢獻的筆記 2 則筆記

17
Gino D.
7 年前
我不知道為什麼 PDOStatement 不會返回「執行時間」和「找到的行數」,所以我建立了一個具有這些屬性的 PDOStatement 擴充類別。

只需將 PDO 物件的「setAttribute」設定為 $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;
}
}
?>
3
nmurzin at mail dot ru
3 年前
我想我找到一種執行受保護的 SQL 查詢,同時又能得知受影響記錄數的方法。
我有一個名為 'tbl_users' 的表格,其中包含以下欄位: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
{
//連線到資料庫。
$db = new PDO($connectionString, DB_LOGIN, DB_PASS);
}
catch(PDOException $e)
{
die("錯誤: ".$e->getMessage());
}
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

try
{

//減少使用者 'nick1' 的年齡。
$prep1 = $db->prepare("UPDATE tbl_users SET age=age-1 WHERE login='nick1'");

//增加使用者 'nick2' 的年齡。
$prep2 = $db->prepare("UPDATE tbl_users SET \r\n age=age+1 WHERE login='nick2'");

//開始交易。
$db->beginTransaction(); //表格類型必須是 InnerDB!

//我們假設一切都會順利。
$flagDone = true;

//exec() 方法會返回受查詢影響的行數。
//$prep1->queryString 已經是一個已跳脫的 SQL 字串。
$result = $db->exec($prep1->queryString);
if($result==false || $result!=1) //var_dump($result) - int(1) 或 bool(false)。
$flagDone = false;

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

if($flagDone)
{
if($db->commit())
echo "交易成功";
}
else{
echo "交易失敗";
$db->rollback();
}
echo "<br>";

}
catch(PDOException $e)
{
die("錯誤: ".$e->getMessage());
}
To Top