溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

獲取PDO對象并設(shè)置屬性的方法

發(fā)布時間:2020-08-21 11:29:35 來源:億速云 閱讀:168 作者:小新 欄目:編程語言

這篇文章給大家分享的是有關(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_UNIQUEPDO::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é)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細(xì)節(jié)

免責(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)容。

AI