[英]Having trouble with associative array structure in PHP
不太確定如何表達這個問題,但是我在編寫的類中遇到了一個關聯數組的結構問題。 代碼的相關部分如下所示:
class User {
public $userData;
function getUserData() {
$stmt = $this->conn->prepare('SELECT * FROM user_table WHERE id = :id');
$stmt->execute(array('id' => $this->ID));
$row = $stmt->fetchAll();
foreach($row AS $key => $val) {
$this->userData[$key] = $val;
}
return $this->userData;
}
我希望能夠使用它來設置類屬性,以便可以像這樣訪問它們:
$this->userData['username'];
例如,但這對我不起作用。 相反,我必須像這樣訪問它們才能起作用:
$this->userData[0]['username'];
我必須添加數組索引才能訪問任何數據,我不想這樣做,但是我不知道如何解決此問題。
這與PDOStatement :: fetchAll()返回行數據的方式有關。
即使您僅選擇一行,它仍將返回行索引(零),即,如果您這樣做的話
print_r($row);
你會得到這樣的東西
Array
(
[0] => Array
(
[username] => Roy
[0] => Roy
)
)
請注意,默認情況下,fetchAll()返回數據中的每一列兩次-按列名一次,按列索引一次
您為變量$row
命名的事實可能是絆倒您的一部分-語義上應該是$rows
。
要解決此問題,您有幾種選擇
直接訪問結果的第一行
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC); // Notice the addtion of the foreach($rows[0] AS $key => $val)
$row = $stmt->fetch(PDO::FETCH_ASSOC); // Notice the addtion of the foreach($row AS $key => $val)
但是在兩種情況下,都不需要for循環。 你可以做
$this->userData = $stmt->fetch(PDO::FETCH_ASSOC);
最后,我必須質疑為什么User::$userData
是公開的,但是您也為此寫了一個吸氣劑(從學術上講,它甚至不是吸氣劑-它是一個訪存器)
人們在編寫返回結果的方法時使用get作為選擇動詞並不罕見。 然而,有思想的同樣廣泛的學校,干將應限於只返回類成員。 在我工作的地方,我們在編碼標准中包含有關方法命名的這些行
get
器或設置器的方法應避免使用get
和set
作為前綴
這意味着開發人員可以編寫不僅返回類屬性的get*()
方法,而且鼓勵他們不要這樣做 。
因此,當我說“提取程序”時,這是一個口語化的術語,並不是真正的通用軟件工程術語的一部分。
這是一個示例,其中我們對關注點進行了嚴格的分離 。 用戶數據的“獲取”和“獲取”分別具有自己的實現,即自己的方法。
class User
{
private $userData = null;
/**
* Lazy-load-style getter for $userData
*
* @return array
*/
public function getUserData()
{
if (null === $this->userData)
{
$this->userData = $this->fetchUserData();
}
return $this->userData;
}
/**
* Fetch the user's data from the database
*
* @return array Associative array of user data where the keys
* are column names
*/
private function fetchUserData()
{
$stmt = $this->conn->prepare('SELECT * FROM user_table WHERE id = :id');
$stmt->execute(array('id' => $this->ID));
return $stmt->fetch(PDO::FETCH_ASSOC);
}
}
盡管我建議向User::fetchUserData()
添加保護檢查,以防PDO::fetch()
返回FALSE 。 也許像
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if (false === $user)
{
throw new Exception("User with id ($this->ID) not found");
}
問題是您的$stmt->fetchAll()
,在您的查詢中確實暗示您正在嘗試獲取單行。 您需要將其替換為$stmt->fetch()
原因是因為在您的示例中,每行的$ key是行索引,所以對於第0行,您的賦值語句是:
$this->userData[0] = $val;
您要做的是使用兩個字段的值將值分配給數組(我猜):
$this->userData[$val['field1']] = $val['field2'];
要么,
$this->userData['username'] = $val['username'];
但是,我認為真正的問題是,您試圖獲取一行並取而代之以獲取結果數組-並在無意中遍歷行,而不是您認為的字段。
如果要查找單個用戶記錄,則需要使用關聯的單個訪存,而不是fetchAll:
class User {
public $userData;
function getUserData() {
$stmt = $this->conn->prepare('SELECT * FROM user_table WHERE id = :id');
$stmt->execute(array('id' => $this->ID));
$this->userData = $stmt->fetch(PDO::FETCH_ASSOC);
return $this->userData;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.