您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關(guān)獲取PDO對象并設(shè)置屬性的方法的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考。一起跟隨小編過來看看吧。
與任何其他數(shù)據(jù)庫擴展一樣,PDO可以直接從所選數(shù)據(jù)創(chuàng)建現(xiàn)有類的實例。但是,與其他擴展不同的是,PDO為強大而靈活的對象操作提供了許多特性。
獲取單個對象
要從查詢結(jié)果創(chuàng)建單個對象,有兩種方法。
1.使用熟悉的fetch()方法:
class User {}; $stmt = $pdo->query('SELECT name FROM users LIMIT 1'); $stmt->setFetchMode(PDO::FETCH_CLASS, 'User'); $user = $stmt->fetch();
2.專用的fetchObject()方法:
class User {}; $user = $pdo->query('SELECT name FROM users LIMIT 1')->fetchObject('User');
雖然這兩個代碼段都將為你提供相同的User類實例,
/* object(User)#3 (1) { ["name"] => string(4) "John" } */
后一種方法看起來絕對更簡潔。此外,如果使用了fetch()方法,但是沒有使用這樣的名稱定義類,則將靜默返回一個數(shù)組,而使用fetchObject()將拋出一個適當(dāng)?shù)腻e誤。
獲取對象數(shù)組
當(dāng)然,上面描述的兩種方法都可以與一個熟悉的while語句一起使用,從數(shù)據(jù)庫中獲取結(jié)果行。
使用一個方便的fetchAll()方法一次獲取對象數(shù)組中所有返回的記錄:
class User {}; $users = $pdo->query('SELECT name FROM users')->fetchAll(PDO::FETCH_CLASS, 'User');
將給你一個數(shù)組,由一個User類的對象組成,返回數(shù)據(jù)填充屬性:
/* array(2) { [0]=> object(User)#3 (1) { ["name"] => string(4) "John" } [1]=> object(User)#4 (1) { ["name"]=> string(4) "Mike" } } */
注意,你可以將此模式與PDO::FETCH_UNIQUE和PDO::FETCH_GROUP組合使用,以獲得由唯一字段索引的結(jié)果數(shù)組,或者分別使用非唯一字段對結(jié)果進(jìn)行分組。
例如,下面的代碼將返回一個數(shù)組,其中記錄id將用作數(shù)組索引而不是連續(xù)數(shù)字。
class User {}; $stmt = $pdo->query('SELECT id, id, name, car FROM users'); $users = ->fetchAll(PDO::FETCH_CLASS|PDO::FETCH_UNIQUE, 'User');
分配類屬性
無論選擇哪種方法,查詢返回的所有列都將按照以下規(guī)則分配給對應(yīng)的類屬性:
1.如果有一個類屬性,它的名稱與列名相同,則將為該屬性分配列值
2.如果沒有這樣的屬性,那么將調(diào)用一個魔術(shù)方法__set()
3.如果沒有為該類定義__set()方法,那么將創(chuàng)建一個公共屬性并為其分配一個列值。
例如,這段代碼
class User { public $name; } $user = $pdo->query('SELECT * FROM users LIMIT 1')->fetchObject('User');
將給你一個對象,所有屬性自動分配,無論它們是否存在于類中:
/* object(User)#3 (4) { ["id"] => string(3) "104" ["name"] => string(4) "John" ["sex"] => string(4) "male" ["car"] => string(6) "Toyota" } */
從這一點可以看出,為了避免自動創(chuàng)建屬性,你可以使用魔術(shù)方法__set()過濾掉屬性。最簡單的過濾技術(shù)就是一個空的__set()方法。使用它,只會設(shè)置現(xiàn)有的屬性:
class User { private $name; public function __set($name, $value) {} } $user = $pdo->query('SELECT * FROM users LIMIT 1')->fetchObject('User'); /* array(1) { [0]=> object(User)#3 (1) { ["name":"User":private]=> string(4) "John" } } */
如上PDO還可以為私有屬性分配值。
將構(gòu)造函數(shù)參數(shù)傳遞給對象
當(dāng)然,對于新創(chuàng)建的對象,我們可能需要提供構(gòu)造函數(shù)參數(shù)。為此,fetchObject()和fetchAll()方法都有一個專用的參數(shù),你可以使用它以數(shù)組的形式傳遞構(gòu)造函數(shù)參數(shù)。
假設(shè)我們有一個類User,它有一個car屬性,可以通過提供的變量在構(gòu)造函數(shù)中設(shè)置:
class User { public function __construct($car) { $this->car = $car; } }
在獲取記錄時,我們應(yīng)該添加一個帶有構(gòu)造函數(shù)參數(shù)的數(shù)組:
$users = $pdo->query('SELECT name FROM users LIMIT 1') ->fetchAll(PDO::FETCH_CLASS, 'User', ['Caterpillar']); $user = $pdo->query('SELECT name FROM users LIMIT 1') ->fetchObject('User',['Caterpillar']);
/* object(User)#3 (2) { ["name"] => string(4) "John" ["car"] => string(11) "Caterpillar" } */
可以看到,數(shù)據(jù)庫中的值被覆蓋了,因為默認(rèn)情況下PDO在調(diào)用構(gòu)造函數(shù)之前分配類屬性。這可能是一個問題,但很容易解決:
在調(diào)用構(gòu)造函數(shù)后設(shè)置類屬性
mysql_fetch_object()注釋:
如果你使用mysql_fetch_object并指定一個類——屬性將在構(gòu)造函數(shù)執(zhí)行之前設(shè)置。這通常不是問題,但是如果你的屬性是通過__set()魔術(shù)方法設(shè)置的,那必須首先執(zhí)行構(gòu)造函數(shù)邏輯,否則可能會導(dǎo)致一些主要問題。
可惜mysql是一個mysqli擴展,但我們使用的是PDO。因此,有一種方法可以告訴PDO在構(gòu)造函數(shù)執(zhí)行之后分配屬性。為此,必須使用PDO::FETCH_PROPS_LATE常量。
使用fetchAll()將非常簡單,
class User { public function __construct($car) { $this->car = $car; } } $stmt = $pdo->query('SELECT name, car FROM users LIMIT 1'); $users = $stmt->fetchAll(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, 'User', ['Caterpillar']);
在獲取單個行時,我們需要同時調(diào)用setFetchMode()和fetchObject(),這可能有點不方便。
class User { public function __construct($car) { $this->car = $car; } } $stmt = $pdo->query('SELECT name, car FROM users LIMIT 1'); $stmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, 'User'); $user = $stmt->fetchObject('User', ['Caterpillar']); /* object(User)#3 (2) { ["car"] => string(6) "Toyota" ["name"] => string(4) "John" } */
如上這段代碼效率并不高,因為我們必須編寫兩次類名。
或者,我們可以使用fetch():
$stmt = $pdo->query('SELECT name, car FROM users LIMIT 1'); $stmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, 'User', ['Caterpillar']); $user = $stmt->fetch();
但是,如上所述,如果一個類恰好是未定義的,它將無法幫助我們處理錯誤消息。
從數(shù)據(jù)庫中獲取類名
還有一個更有趣的標(biāo)志,它告訴PDO從第一列的值中獲取類名。使用這個標(biāo)志,可以避免使用setFetchMode()和fetch():
$data = $pdo->query("SELECT 'User', name FROM users") ->fetch(PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE); /* object(User)#3 (1) { ["name"]=> string(4) "John" } */
此外,如果可以從同一個查詢創(chuàng)建不同類的對象,那么這種模式將非常有用
class Male {}; class Female {}; $stmt = $pdo->query('SELECT sex, name FROM users'); $users = $stmt->fetchAll(PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE); /* array(6) { [0]=> object(Male)#3 (1) { ["name"]=> string(4) "John" } [1]=> object(Male)#4 (1) { ["name"]=> string(4) "Mike" } [2]=> object(Female)#5 (1) { ["name"]=> string(4) "Mary" } [3]=> object(Female)#6 (1) { ["name"]=> string(5) "Kathy" } }*/
然而,當(dāng)使用這種模式時,似乎不可能在類構(gòu)造函數(shù)中傳遞任何參數(shù)。
更新現(xiàn)有對象
除了創(chuàng)建新對象,PDO還可以更新現(xiàn)有對象。只使用setFetchMode(),它將現(xiàn)有變量作為參數(shù)。顯然,使用fetchAll()是無用的。
class User { public $name; public $state; public function __construct() { $this->name = NULL; } } $user = new User; $user->state = "up'n'running"; var_dump($user); $stmt = $pdo->query('SELECT name FROM users LIMIT 1'); $stmt->setFetchMode(PDO::FETCH_INTO, $user); $data = $stmt->fetch(); var_dump($data, $user); /* object(Foo)#2 (2) { ["name"] => NULL ["state"] => string(12) "up'n'running" } object(Foo)#2 (2) { ["name"] => string(4) "John" ["state"] => string(12) "up'n'running" } object(Foo)#2 (2) { ["name"] => string(4) "John" ["state"] => string(12) "up'n'running" } */
如上,fetch()調(diào)用返回的是相同的對象,這在我看來是多余的。還要注意,與PDO::FETCH_CLASS不同,這種模式不分配私有屬性。
感謝各位的閱讀!關(guān)于獲取PDO對象并設(shè)置屬性的方法就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。