PHP Conference Japan 2024

PDOStatement::fetchAll

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

PDOStatement::fetchAll 從結果集中取得剩餘的資料列

說明

public PDOStatement::fetchAll(int $mode = PDO::FETCH_DEFAULT): array
public PDOStatement::fetchAll(int $mode = PDO::FETCH_COLUMN, int $column): array
public PDOStatement::fetchAll(int $mode = PDO::FETCH_CLASS, string $class, ?array $constructorArgs): array
public PDOStatement::fetchAll(int $mode = PDO::FETCH_FUNC, callable $callback): array

參數

mode

控制傳回陣列的內容,如 PDOStatement::fetch() 中所述。預設值為 PDO::ATTR_DEFAULT_FETCH_MODE (預設為 PDO::FETCH_BOTH)

若要傳回一個由結果集中單一欄的所有值組成的陣列,請指定 PDO::FETCH_COLUMN。您可以使用 column 參數指定您想要的欄位。

若要依據特定欄位的值為結果陣列建立索引(而非連續數字),請在 SQL 的欄位清單中將此欄位名稱放在第一個,並使用 PDO::FETCH_UNIQUE。此欄位必須僅包含唯一值,否則某些資料將會遺失。

若要將結果以三維陣列的形式分組,並依據指定的欄位值建立索引,請在 SQL 的欄位清單中將此欄位名稱放在第一個,並使用 PDO::FETCH_GROUP

若要將結果以二維陣列的形式分組,請使用按位 OR 運算子將 PDO::FETCH_GROUPPDO::FETCH_COLUMN 結合使用。結果將依據第一欄分組,而陣列元素的值將是第二欄中對應項目的清單陣列。

以下是依據取得模式而定的動態參數。它們不能與具名參數一起使用。
column

PDO::FETCH_COLUMN 一起使用。傳回指示的 0 索引欄位。

class

PDO::FETCH_CLASS 一起使用。傳回指定類別的實例,並將每列的欄位對應至類別中的具名屬性。

constructorArgs

mode 參數為 PDO::FETCH_CLASS 時,自訂類別建構子的引數。

callback

PDO::FETCH_FUNC 一起使用。傳回呼叫指定函式的結果,並使用每列的欄位作為呼叫中的參數。

傳回值

PDOStatement::fetchAll() 會傳回一個陣列,其中包含結果集中的所有剩餘資料列。該陣列將每一列表示為欄位值的陣列,或是其屬性對應於每個欄位名稱的物件。如果沒有要擷取的結果,則會傳回一個空陣列。

使用此方法來擷取大型結果集會對系統資源和可能的網路資源產生沉重的需求。與其擷取所有資料並在 PHP 中進行操作,不如考慮使用資料庫伺服器來操作結果集。例如,在 SQL 中使用 WHERE 和 ORDER BY 子句,以在擷取和使用 PHP 處理結果之前限制結果。

錯誤/例外

如果屬性 PDO::ATTR_ERRMODE 設定為 PDO::ERRMODE_WARNING,則會發出層級為 E_WARNING 的錯誤。

如果屬性 PDO::ATTR_ERRMODE 設定為 PDO::ERRMODE_EXCEPTION,則會擲回 PDOException

變更記錄

版本 說明
8.0.0 此方法現在一律傳回 array,而先前可能會在失敗時傳回 false

範例

範例 #1 從結果集中取得所有剩餘資料列

<?php
$sth
= $dbh->prepare("SELECT name, colour FROM fruit");
$sth->execute();

/* 從結果集中擷取所有剩餘資料列 */
print "從結果集中擷取所有剩餘資料列:\n";
$result = $sth->fetchAll();
print_r($result);
?>

上述範例將會輸出類似如下的內容

Fetch all of the remaining rows in the result set:
Array
(
    [0] => Array
        (
            [name] => apple
            [0] => apple
            [colour] => red
            [1] => red
        )

    [1] => Array
        (
            [name] => pear
            [0] => pear
            [colour] => green
            [1] => green
        )

    [2] => Array
        (
            [name] => watermelon
            [0] => watermelon
            [colour] => pink
            [1] => pink
        )

)

範例 #2 從結果集中擷取單一欄的所有值

以下範例示範如何從結果集中傳回單一欄的所有值,即使 SQL 陳述式本身可能傳回每列多個欄位。

<?php
$sth
= $dbh->prepare("SELECT name, colour FROM fruit");
$sth->execute();

/* 擷取第一欄的所有值 */
$result = $sth->fetchAll(PDO::FETCH_COLUMN, 0);
var_dump($result);
?>

上述範例將會輸出類似如下的內容

Array(3)
(
    [0] =>
    string(5) => apple
    [1] =>
    string(4) => pear
    [2] =>
    string(10) => watermelon
)

範例 #3 將所有值依單一欄位分組

以下範例示範如何傳回一個關聯陣列,該陣列會依據結果集中指定欄位的值進行分組。該陣列包含三個鍵:值 applepear 會以包含兩種不同顏色的陣列傳回,而 watermelon 則會以只包含一種顏色的陣列傳回。

<?php
$insert
= $dbh->prepare("INSERT INTO fruit(name, colour) VALUES (?, ?)");
$insert->execute(array('apple', 'green'));
$insert->execute(array('pear', 'yellow'));

$sth = $dbh->prepare("SELECT name, colour FROM fruit");
$sth->execute();

/* 依第一欄分組值 */
var_dump($sth->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_GROUP));
?>

上述範例將會輸出類似如下的內容

array(3) {
  ["apple"]=>
  array(2) {
    [0]=>
    string(5) "green"
    [1]=>
    string(3) "red"
  }
  ["pear"]=>
  array(2) {
    [0]=>
    string(5) "green"
    [1]=>
    string(6) "yellow"
  }
  ["watermelon"]=>
  array(1) {
    [0]=>
    string(5) "pink"
  }
}

範例 #4 為每個結果實例化一個類別

以下範例示範 PDO::FETCH_CLASS 擷取樣式的行為。

<?php
class fruit {
public
$name;
public
$colour;
}

$sth = $dbh->prepare("SELECT name, colour FROM fruit");
$sth->execute();

$result = $sth->fetchAll(PDO::FETCH_CLASS, "fruit");
var_dump($result);
?>

上述範例將會輸出類似如下的內容

array(3) {
  [0]=>
  object(fruit)#1 (2) {
    ["name"]=>
    string(5) "apple"
    ["colour"]=>
    string(5) "green"
  }
  [1]=>
  object(fruit)#2 (2) {
    ["name"]=>
    string(4) "pear"
    ["colour"]=>
    string(6) "yellow"
  }
  [2]=>
  object(fruit)#3 (2) {
    ["name"]=>
    string(10) "watermelon"
    ["colour"]=>
    string(4) "pink"
  }
  [3]=>
  object(fruit)#4 (2) {
    ["name"]=>
    string(5) "apple"
    ["colour"]=>
    string(3) "red"
  }
  [4]=>
  object(fruit)#5 (2) {
    ["name"]=>
    string(4) "pear"
    ["colour"]=>
    string(5) "green"
  }
}

範例 #5 為每個結果呼叫函式

以下範例示範 PDO::FETCH_FUNC 擷取樣式的行為。

<?php
function fruit($name, $colour) {
return
"{$name}: {$colour}";
}

$sth = $dbh->prepare("SELECT name, colour FROM fruit");
$sth->execute();

$result = $sth->fetchAll(PDO::FETCH_FUNC, "fruit");
var_dump($result);
?>

上述範例將會輸出類似如下的內容

array(3) {
  [0]=>
  string(12) "apple: green"
  [1]=>
  string(12) "pear: yellow"
  [2]=>
  string(16) "watermelon: pink"
  [3]=>
  string(10) "apple: red"
  [4]=>
  string(11) "pear: green"
}

另請參閱

新增筆記

使用者貢獻筆記 27 筆記

99
simplerezo at gmail dot com
7 年前
我仍然不明白為什麼 FETCH_KEY_PAIR 沒有在這裡記錄 (https://php.dev.org.tw/manual/fr/pdo.constants.php),因為它可能非常有用!

<?php
var_dump
($pdo->query('select id, name from table')->fetchAll(PDO::FETCH_KEY_PAIR));
?>

這將會顯示
array(2) {
[2]=>
string(10) "name2"
[5]=>
string(10) "name5"
}
51
dyukemedia at gmail dot com
9 年前
讓 foreach 能夠順利處理來自 PDO FetchAll() 的一些資料
我不了解如何正確使用 foreach 的 $value 部分,我希望這對其他人有所幫助。
範例
<?php
$stmt
= $this->db->prepare('SELECT title, FMarticle_id FROM articles WHERE domain_name =:domain_name');
$stmt->bindValue(':domain_name', $domain);
$stmt->execute();
$article_list = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
這會產生

array (size=2)
0 =>
array (size=2)
'title' => string 'About Cats Really Long title for the article' (length=44)
'FMarticle_id' => string '7CAEBB15-6784-3A41-909A-1B6D12667499' (length=36)
1 =>
array (size=2)
'title' => string 'another cat story' (length=17)
'FMarticle_id' => string '0BB86A06-2A79-3145-8A02-ECF6EA5C405C' (length=36)

然後使用
<?php
foreach ($article_list as $row => $link) {
echo
'<a href="'. $link['FMarticle_id'].'">' . $link['title']. '</a></br>';
}
?>
37
esw at pixeloution dot removeme dot com
14 年前
有趣的是,當您使用 fetchAll 時,物件的建構函式會在屬性指派之後呼叫。例如

<?php
class person {
public
$name;

function
__construct() {
$this->name = $this->name . " is my name.";
}
}

# 在此使用 PDO 設定從資料庫的 select
$obj = $STH->fetchALL(PDO::FETCH_CLASS, 'person');
?>

會導致 ' is my name' 被附加到所有名稱欄位。但是,如果您稍微不同地呼叫它

<?php
$obj
= $obj = $STH->fetchAll(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'person');
?>

那麼建構函式將在屬性被賦值之前被呼叫。我找不到任何地方有記載這一點,所以我認為在這裡添加一個註釋會很好。
21
Daniel Hofmann
15 年前
請注意:如果您執行 OUTER LEFT JOIN 並將 PDO FetchALL 設定為 PDO::FETCH_ASSOC,則您在 OUTER LEFT JOIN 中使用的任何主鍵,如果 JOIN 中沒有返回任何記錄,將會被設定為空白。

例如
<?php
//查詢 product 表格,並 join 到 image 表格,並為每個產品返回任何圖像(如果有的話)
$sql = "SELECT * FROM product, image
LEFT OUTER JOIN image ON (product.product_id = image.product_id)"
;

$array = $stmt->fetchAll(PDO::FETCH_ASSOC);

print_r($array);
?>

產生的陣列會像這樣

陣列
(
[0] => 陣列
(
[product_id] =>
[notes] => "這個產品..."
[brand] => "Best Yet"
...

解決方法是在 SELECT 子句中簡單地指定您的欄位名稱,而不是使用 * 作為萬用字元,或者,您也可以在 * 之外指定欄位。以下範例會正確返回 product_id 欄位

<?php
$sql
= "SELECT *, product.product_id FROM product, image
LEFT OUTER JOIN image ON (product.product_id = image.product_id)"
;

$array = $stmt->fetchAll(PDO::FETCH_ASSOC);

print_r($array);
?>

產生的陣列會像這樣

陣列
(
[0] => 陣列
(
[product_id] => 3
[notes] => "這個產品..."
[brand] => "Best Yet"
...
20
Anonymous
13 年前
請注意,fetchAll() 對於大型資料集可能非常耗費記憶體。我的記憶體限制設定為 160 MB,這是我嘗試時發生的情況

<?php
$arr
= $stmt->fetchAll();
// Fatal error: Allowed memory size of 16777216 bytes exhausted
?>

如果您要迴圈遍歷 fetchAll() 的輸出陣列,請改用 fetch() 來盡量減少記憶體使用量,如下所示

<?php
while ($arr = $stmt->fetch()) {
echo
round(memory_get_usage() / (1024*1024),3) .' MB<br />';
// do_other_stuff();
}
// 同一個查詢的最後一行只顯示 28.973 MB 的使用量
?>
11
michael dot arnauts at gmail dot com
10 年前
如果您想使用 PDO::FETCH_CLASS,但不喜歡所有值都是字串類型,您始終可以使用指定的類別的 __construct 函數將它們轉換為不同的類型。

另一種方法是使用 mysqlnd,但似乎我必須重新編譯 PHP 才能做到這一點。

<?php

class Cdr {
public
$a; // int
public $b; // float
public $c; // string

public function __construct() {
$this->a = intval($this->a);
$this->b = floatval($this->b);
}

}

// ...
$arrCdrs = $objSqlStatement->fetchAll(PDO::FETCH_CLASS, 'Cdr');

?>
6
info at yuriblanc dot it
9 年前
文件中遺漏了一些東西。
例如,如果您嘗試 fetchAll(PDO::CLASS, "Class"),它有時會返回一個具有 NULL 值的物件陣列,但是獲取的物件計數與表格行數對應。

這樣運作良好
fetchAll(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, "Class");

例如

$stm = $pdo->prepare("SELECT * FROM Fruit");
$stm->execute();
$stm->fetchAll(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, "Fruit");
21
Anonymous
16 年前
如果沒有返回任何行,fetchAll 會返回一個空陣列。
1
shaunc
1 年前
請注意,\PDO::FETCH_DEFAULT 直到 PHP 8.0.7 和 8.1.0 才引入。它會在較早的版本中拋出未定義常數錯誤。
3
Anonymous
7 年前
使用 PDO::FETCH_COLUMN 與 PDO::FETCH_GROUP 時要小心。預設情況下,結果會按第一欄(索引 0)分組,並返回第二欄(索引 1)。但是,如果您提供 fetch 參數,它不會影響返回的欄位,而是會影響分組欄位。如果明確設定分組欄位,則會返回第一欄而不是第二欄。

<?php
$insert
= $dbh->prepare("INSERT INTO people(id, gender) VALUES (?, ?)");
$insert->execute(array('2', 'female'));
$insert->execute(array('3', 'female'));
$insert->execute(array('4', 'female'));
$insert->execute(array('5', 'male'));
$insert->execute(array('6', 'male'));

$sth = $dbh->prepare("SELECT gender, id FROM people");
$sth->execute();

/* 按第一欄分組值 */
var_dump($sth->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_GROUP));
?>
返回
<?php
array (size=2)
'female' =>
array (
size=3)
0 => string '2' (length=1)
1 => string '3' (length=1)
2 => string '4' (length=1)
'male' =>
array (
size=2)
0 => string '5' (length=1)
1 => string '6' (length=1)
?>

但是,
<?php
var_dump
($sth->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_GROUP, 0));
?>
返回
<?php
array (size=2)
'female' =>
array (
size=3)
0 => string 'female' (length=1)
1 => string 'female' (length=1)
2 => string 'female' (length=1)
'male' =>
array (
size=2)
0 => string 'male' (length=1)
1 => string 'male' (length=1)
?>
and
<?php
var_dump
($sth->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_GROUP, 1));
?>
返回
<?php
array (size=5)
2 =>
array (
size=1)
0 => string 'female' (length=1)
3 =>
array (
size=1)
0 => string 'female' (length=1)
4 =>
array (
size=1)
0 => string 'female' (length=1)
5 =>
array (
size=1)
0 => string 'male' (length=1)
6 =>
array (
size=1)
0 => string 'male' (length=1)
?>

第一欄會被回傳,並且會根據提供的欄位索引進行分組。
5
Hayley Watson
13 年前
如果您使用 PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE 旗標將欄位對應到物件屬性,fetchAll() 在執行對應時,會使用您的物件所擁有的任何 __set() 方法。
3
mxrgus
15 年前
在方法主體中

return $pstmt->fetchAll() or die("bad");

不會回傳正確的值,而是回傳 "1"。
3
stas at metalinfo dot ru
18 年前
請注意,只有在選擇兩個欄位時才能使用 PDO::FETCH_COLUMN|PDO::FETCH_GROUP 配對,不像 DB_common::getAssoc(),當 grouping 設定為 true 時。
6
harlequin2 at gmx dot de
16 年前
在 Oracle 和 MSSQL 上還支援另一種提取模式
PDO::FETCH_ASSOC

> 只提取欄位名稱,並省略數字索引。

如果您想要從 SQL 陳述式回傳所有欄位,並以欄位鍵作為表格標題,可以簡單地這樣做

<?php
$dbh
= new PDO("DS", "USERNAME", "PASSWORD");
$stmt = $dbh->prepare("SELECT * FROM tablename");
$stmt->execute();
$arrValues = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 開啟表格
print "<table wdith=\"100%\">\n";
print
"<tr>\n";
// 新增表格標題
foreach ($arrValues[0] as $key => $useless){
print
"<th>$key</th>";
}
print
"</tr>";
// 顯示資料
foreach ($arrValues as $row){
print
"<tr>";
foreach (
$row as $key => $val){
print
"<td>$val</td>";
}
print
"</tr>\n";
}
// 關閉表格
print "</table>\n";
?>
2
mrshelly at hotmail dot com
16 年前
PHP 從 SQL Server 2005 提取資料
如果欄位的資料型別為 varchar(nvarchar),則只會提取 255 個字元。但 "text" 資料型別則沒問題。

所以,請注意!將 'varchar' 或 'nvarchar' (長度 > 255) 變更為 'text' 資料型別。

希望能幫助到您。

<?php

$user
= 'sa';
$pass = 'pass';

$conn = new PDO('mssql:host=127.0.0.1; dbname=tempdb;', $user, $pass);

$mainSQL = "SELECT field_varchar, field_text FROM table1";
$sth = $conn->prepare($mainSQL);
$sth->setFetchMode(PDO::FETCH_ASSOC);
$sth->execute();
$retRows = $sth->fetchAll();
// field_varchar 欄位只會提取 255 個字元 (最多)
// field_text 沒問題。

var_dump($retRows);

unset(
$sth); unset($conn);

?>
1
akira at etnforum dot com
9 年前
可能有些使用者需要將他們的 MySQL 類別升級為 PDO 類別。提取結果的方式從 while 迴圈變更為 foreach 迴圈。對於希望使用 while 迴圈提取結果的人,這裡有一個簡單的技巧。

<?php

$db
= new DB();
$query = $db->prepare("SELECT * FROM CPUCategory");
$query = $db->execute();
$result = $db->fetchAll();
var_dump($result);

?>

輸出結果會是
array(2) {
[0]=> array(2) {
["ccatid"]=> int(1)
["ccatname"]=> string(5) "Intel"
}
[1]=> array(2) {
["ccatid"]=> int(2)
["ccatname"]=> string(3) "AMD"
}
}

永遠不會看起來像舊函數的輸出。
[原始樣式] mysql_fetch_array($query)
[MYSQL 類別] $db->fetch_array($query)

您可能會放棄。
但有一種簡單的方法可以使用 while 迴圈來提取結果。

<?php

$db
= new DB();
$query = $db->prepare("SELECT * FROM CPUCategory");
$query = $db->execute();
$result = $db->fetchAll();
$row = array_shift($result);
// 如果您現在需要提取它們,請將其放入 while 迴圈中,如下所示:
// while($row = array_shift($result)) { ... }

var_dump($row);

?>

輸出將會是一個單一陣列,而 while 迴圈會回傳 TRUE
array(2) {
["ccatid"]=> int(1)
["ccatname"]=> string(5) "Intel"
}

因此,在提取這個列之後,while 迴圈會再次執行,並提取下一列,直到所有列都被提取,然後 while 迴圈將會回傳 false。(就像舊函數所做的一樣)

當您需要升級到 PDO 類別時,不需要修改太多程式碼,並且記住即可。
1
Dennis
14 年前
錯誤
SQLSTATE[HY000]: 一般錯誤:2014 無法在其他未緩衝的查詢處於活動狀態時執行查詢。請考慮使用 PDOStatement::fetchAll()。或者,如果您的程式碼只會在 mysql 上執行,您可以透過設定 PDO::MYSQL_ATTR_USE_BUFFERED_QUERY 屬性來啟用查詢緩衝。

如果您使用類似的程式碼

while ($row = $query->fetchObject()) {
[...]
}

請嘗試改用以下程式碼

$rows = $query->fetchAll(PDO::FETCH_CLASS, 'ArrayObject');

foreach ($rows as $row) {
[...]
}
1
php at erikthiart dot com
3 年前
我在這裡新增這個,因為我似乎找不到任何清楚且容易找到的 PDO::FETCH_GROUP 範例和說明,以及它如何透過範例運作。

我發現當您需要處理任何形式的分組時,這是 fetchAll() 中最有用的模式之一。

基本上,PDO 可以根據所選的第一個欄位將結果分組到巢狀陣列中。

範例

<?php

$data
= $pdo->query('SELECT sex, name, car FROM users')->fetchAll(PDO::FETCH_GROUP);

/* array (
'male' => array ( 0 =>
array (
'name' => 'John',
'car' => 'Toyota',
),
1 => array (
'name' => 'Mike',
'car' => 'Ford',
),
),
'female' => array (
0 => array (
'name' => 'Mary',
'car' => 'Mazda',
),
1 => array (
'name' => 'Kathy',
'car' => 'Mazda',
),
),
) */

?>

提示:如果您需要按第一個欄位以外的其他欄位分組資料,您也可以這樣做

<?php
SELECT sex
, users.* FROM users
?>
0
herhor67 at interia dot pl
3 年前
我注意到一個非常奇怪(至少對我來說)的行為。也許它可以幫助也會遇到這個問題的人。

<?php
$stmt
= new PDOStatement();
$foo = $stmt->fetchAll();
var_dump($foo);

$stmt = $pdo->prepare('SELECT VERSION()');
$foo = $stmt->fetchAll();
var_dump($foo);

$stmt = $pdo->prepare("INSERT INTO `tblnm` (date) VALUES (NOW())");
$stmt->execute();
$foo = $stmt->fetchAll();
var_dump($foo);

$stmt = $pdo->query("INSERT INTO `tblnm` (date) VALUES (NOW())");
$foo = $stmt->fetchAll();
var_dump($foo);
?>

第一個只是一個空的物件,所以 $foo === bool(false)
第二個沒有被執行,所以 $foo === array(0) {}
第三個和第四個在 fetchAll() 時拋出例外
"一般錯誤:2014 在其他未緩衝的查詢活動時無法執行查詢。請考慮使用 PDOStatement::fetchAll()。或者,[...] 您可以透過設定 PDO::MYSQL_ATTR_USE_BUFFERED_QUERY 屬性來啟用查詢緩衝。"

已經使用了 fetchAll(),並且將上述屬性在 true 和 false 之間切換並不會改變任何事情。
這可能是因為 INSERT 沒有任何回傳值。我們可以在 sql 中使用 RETURNING,但它是相當新的功能,所以可能還不是到處都支援。

最後對我有效的是 $pdo->exec() 和 lastInsertId(),因為無論如何我只需要 ID 這個欄位。
<?php
$count
= $pdo->exec('INSERT INTO `tblnm` (date) VALUES (NOW())');
$foo = $pdo->lastInsertId();
var_dump($foo);
?>
然後例如 $foo === string(2) "93"
0
geompse at gmail dot com
4 年前
從 PHP<7.4 升級到 PHP 8.0 時有一個破壞性變更。如果您的類別擴展了 PDOStatement,PHP 8.0 的類型化原型是不相容的
- PHP 7.4 = public PDOStatement::fetchAll ([ int $fetch_style [, mixed $fetch_argument [, array $ctor_args = array() ]]] ) : array
- PHP 8.0 = public PDOStatement::fetchAll ([ int $mode = PDO::FETCH_BOTH[, mixed ...$args] ]) : array

雖然它們對於人類來說是相容的,但 PHP 並不喜歡它
- PHP 7.4 = PHP 警告:(您的類別原型) 的宣告應該與 (PDOStatement 的原型) 相容
- PHP 8.0 = [PhpCompileError] (您的類別原型) 的宣告必須與 (PDOStatement 的原型) 相容

因為第一個是警告,它不是致命的,您可能會很高興使用 PHP 8.0 的原型。我個人的解決方案是停止擴展 PDOStatement,因此重寫相關的類型宣告和條件。
0
Leonardo Costa linux at linuxmanbr dot com dot br
5 年前
具有回傳物件的方法 (PHP 7.2)

class MySql {

public function __construct()
{
parent::__construct();

try{



$options = array
(
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES UTF8"
);

$this->pdo = new PDO('mysql:host=127.0.0.1;dbname=testuser','dbtest', 'xxxxxxx',$options);
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

}catch(PDOException $e) {
print "錯誤!: " . $e->getMessage() . "<br/>";
die();
}
}

public function selectAll(string $sql)
{
$conn = $this->pdo->query($sql);
return $conn->fetchAll(PDO::FETCH_OBJ);
}
}
0
rudigerw at hotmail dot com
6 年前
我感到非常驚訝,您實際上可以組合 PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE | PDO::FETCH_UNIQUE,因為 PDO::FETCH_CLASSTYPE 和 PDO::FETCH_UNIQUE 都說它們會使用第一欄,但結果是 PDO::FETCH_CLASSTYPE 會先執行,然後 PDO::FETCH_UNIQUE 會使用下一欄。這樣您可以使用其中一個表格欄位作為鍵,來建立物件的關聯陣列。例如,像這樣的查詢

'SELECT Class, Id, t.* FROM subscriptions_tbl t'

可能會給您這個結果

陣列
(
[20481086] => WConsumerSubscription 物件
(
[Variant] => 2
[_Expiration:WSubscriptionModel:private] => DateTime 物件
(
[date] => 2018-08-08 00:00:00.000000
[timezone_type] => 3
[timezone] => UTC
)

[Notes] =>
[Id] => 20481086
[_Deleted:protected] => 0
[_VersionNo:protected] => 2
[ContactId] =>
[ConsumerId] => 2
)

[21878324] => WAdminSubscription 物件
(
[Variant] =>
[_Expiration:WSubscriptionModel:private] =>
[Notes] =>
[Id] => 21878324
[_Deleted:protected] => 0
[_VersionNo:protected] => 1
[ContactId] =>
)
)
-2
sidi dot khalifa at live dot fr
5 年前
直接將參數注入 `fetchAll` 中,而不是使用 `bindValue`

$query = "
SELECT
a.total_paid_tax_incl AS prize,
a.date_add AS date_add
FROM orders a
WHERE a.order_id = :seventeen
AND a.name = :name";

// 連線 (在 Symfony 中的範例,您可以使用命名空間 Doctrine\DBAL\Connection 中的 Connection 類別)
$this->connection->fetchAll($query, ['seventeen' => 70, 'name' => 'Sidi'])
-2
janniet at kiekies dot net
10 年前
如果您想要將資料列擷取為您尚未定義類別的物件,您可以執行
<?php
$result
= $q->fetchAll(PDO::FETCH_OBJ);
?>
-1
davey at php dot net
16 年前
當傳遞 PDO::FETCH_CLASS 作為第一個參數時,此方法將接受類別名稱作為第二個選項

<?php
$query
= $pdo->prepare($sql);

$result = $query->execute($values);

if (
$result && $query->rowCount() > 0) {
$records = $query->fetchAll(PDO::FETCH_CLASS, 'Some_Class');
// $record 現在是 Some_Class 物件的陣列
}
?>

- Davey
-1
jeroen dot deklerk at hotmail dot com
8 年前
我一直無法以陣列形式回傳 PDO 查詢結果,因為這些查詢的結果結構 (查詢陣列中包含結果陣列)。現在當在查詢上執行 fetchAll() 時,您會得到以下結果

Array ( [0] = Array ( [key1] => "value1", [key2] => "value2") [1] = Array( [key1] => "value1", [key2] => "value2") )

這是一個較小的陣列,但以這種方式回傳巨大資料庫中的結果,會變得難以讀取給定的陣列。

這就是 foreach 大放異彩的地方!我們都知道 foreach 的基本寫法 (foreach ($array as $key => $value) {...}),但是對於查詢結果,有一個轉折,因為 $key 和 $value 變數都是陣列,其中 $key 是包含結果陣列的查詢陣列,$value 是結果陣列本身。

所以在這個 foreach 中,我們必須直接與 $value 交談以取得我們的結果!這看起來會像這樣

<?php

foreach ($query as $key => $value) {
return
$value["key2"];
}

?>

這已經可以完成工作,但是為了將它們以陣列形式回傳,我們必須稍微更改一下回傳程式碼,就像這樣

<?php

foreach ($query as $key => $value) {
return array (
"key1" => $value["key1"],
"key2" => $value["key2"]
);
}

?>

這個 foreach 迴圈遍歷查詢陣列,就像第一個一樣,但是回傳程式碼不會回傳代表結果陣列 ($key) 的鍵,而只會回傳儲存在 $value 中的結果陣列內的鍵。這給我們一個看起來像這樣的陣列

Array ( [key1] => "value1", [key2] => "value2")

如果編寫正確,這應該會回傳您陣列中的所有值。我仍然遇到 foreach 沒有回傳所有結果的問題,但是這個註解主要是為了展示如何以陣列形式回傳。
-3
ramon at monztro dot com
12 年前
如果您嘗試呼叫 PDOStatement::fetchAll 卻沒有得到預期的結果集(而是空的),請檢查您是否先呼叫了 PDOStatement::execute。

請記住,PDOStatement::fetchAll 並不會執行查詢,它只是將資料放入陣列。

:)
To Top