对 PDO FETCH 指令使用闭包
Use a closure for the PDO FETCH instructions
我想给我的 PDO 结果提供有关如何在稍后迭代时将其自身实例化为对象的说明,但我不想在那之前执行逻辑。
我一直在寻找是否存在此 PDO 功能,但找不到。我想做的基本上是这样的:
public function getUsers()
{
$sql = 'select first_name, last_name, phone, address from users';
return $this->pdo->query($sql, PDO::FETCH_ASSOC, function($row) {
$user = new User();
$user->setName($row['first_name'] . ' ' .$row['last_name'])
->setPhoneNumber($row['phone'])
->setMailingAddress($row['address']);
return $user;
});
}
是否有使用 PHP 尤其是 PDO 实现此目的的好方法?遍历迭代器不是一个可接受的答案。我只想在执行期间迭代此记录集一次。
大概是这样的:
$result = $this->pdo->query($sql, PDO::FETCH_CLASS, 'User');
return $result->fetch();
您可以通过 yield
为此使用生成器。只有当内部指针在某个迭代时,才会产生具体对象。
class User {
public $picture;
public function __construct($pic) {
$this->picture = $pic;
}
}
function getUsers() {
$pdo = new PDO('mysql:host=localhost;dbname=users', 'root', '');
$query = "SELECT * FROM votesusers";
$res = $pdo->query($query);
while ($row = $res->fetch()) {
yield new User($row['picture_id']);
}
}
foreach (getUsers() as $user) {
var_Dump($user);
}
输出:
object(User)[5]
public 'picture' => string '2' (length=1)
object(User)[6]
public 'picture' => string '9' (length=1)
object(User)[5]
public 'picture' => string '6' (length=1)
object(User)[6]
public 'picture' => string '1' (length=1)
您可以创建实现 Iterator
接口的自定义延迟加载集合。这是一个例子:
class LazyCollection implements Iterator
{
private $stmt;
private $callback;
public function __construct(PDOStatement $stmt, Closure $callback)
{
$this->stmt = $stmt;
$this->callback = $callback;
}
public function current()
{
$callback = $this->callback; // required because PHP is silly
return $callback($this->stmt->fetch());
}
/* rest of interface implementation */
}
你会像这样使用它:
$stmt = $this->pdo->query($sql, PDO::FETCH_ASSOC)
$result = new LazyCollection($stmt, function($row) {
return new User($row['name'], $row['phone'], $row['address']);
});
foreach($result as $user)
{
// $user is an instance of User
}
我想给我的 PDO 结果提供有关如何在稍后迭代时将其自身实例化为对象的说明,但我不想在那之前执行逻辑。
我一直在寻找是否存在此 PDO 功能,但找不到。我想做的基本上是这样的:
public function getUsers()
{
$sql = 'select first_name, last_name, phone, address from users';
return $this->pdo->query($sql, PDO::FETCH_ASSOC, function($row) {
$user = new User();
$user->setName($row['first_name'] . ' ' .$row['last_name'])
->setPhoneNumber($row['phone'])
->setMailingAddress($row['address']);
return $user;
});
}
是否有使用 PHP 尤其是 PDO 实现此目的的好方法?遍历迭代器不是一个可接受的答案。我只想在执行期间迭代此记录集一次。
大概是这样的:
$result = $this->pdo->query($sql, PDO::FETCH_CLASS, 'User');
return $result->fetch();
您可以通过 yield
为此使用生成器。只有当内部指针在某个迭代时,才会产生具体对象。
class User {
public $picture;
public function __construct($pic) {
$this->picture = $pic;
}
}
function getUsers() {
$pdo = new PDO('mysql:host=localhost;dbname=users', 'root', '');
$query = "SELECT * FROM votesusers";
$res = $pdo->query($query);
while ($row = $res->fetch()) {
yield new User($row['picture_id']);
}
}
foreach (getUsers() as $user) {
var_Dump($user);
}
输出:
object(User)[5]
public 'picture' => string '2' (length=1)
object(User)[6]
public 'picture' => string '9' (length=1)
object(User)[5]
public 'picture' => string '6' (length=1)
object(User)[6]
public 'picture' => string '1' (length=1)
您可以创建实现 Iterator
接口的自定义延迟加载集合。这是一个例子:
class LazyCollection implements Iterator
{
private $stmt;
private $callback;
public function __construct(PDOStatement $stmt, Closure $callback)
{
$this->stmt = $stmt;
$this->callback = $callback;
}
public function current()
{
$callback = $this->callback; // required because PHP is silly
return $callback($this->stmt->fetch());
}
/* rest of interface implementation */
}
你会像这样使用它:
$stmt = $this->pdo->query($sql, PDO::FETCH_ASSOC)
$result = new LazyCollection($stmt, function($row) {
return new User($row['name'], $row['phone'], $row['address']);
});
foreach($result as $user)
{
// $user is an instance of User
}