如何使用枚举 属性 使用 PDO 将数据提取到 class 中?
How to fetch data with PDO into class with enum property?
自从枚举功能在 PHP8.1 中发布以来,我想知道如何使用 PDO 从我的数据库中将数据提取到具有 ENUM 属性.
的对象中
我有以下枚举:
enum UserType{
case Master: 1;
case Admin: 2;
case Manager: 3;
}
我有以下 class:
class User{
private int $id;
private string $name;
private UserType $userType;
}
每次我尝试执行下面的代码时,我都会收到错误 无法将 int 分配给 属性 User::$userType of type UserType
Database::getInstance()->fetchObject(sql: "SELECT id, name, userType FROM user WHERE id = 1", class_name: User::class);
我想知道是否有办法使上面的代码正常工作,或者在我的代码中实现新枚举功能的最佳方法是什么。
我的 fetchObject 代码:
public function fetchObject($sql, array $args = array(), string $class_name = "stdClass"): mixed
{
$sql = self::$instance->prepare($sql);
if(empty($args)){
$sql->execute();
} else{
$sql->execute($args);
}
$object = $sql->fetchObject($class_name);
$sql->closeCursor();
return $object;
}
fetchObject()
做不到。原因是您不能将 int
分配给 UserType
类型的 属性。您可以使用魔术方法 __set()
,但您不必声明 属性(强烈不推荐)。
您可以将 __set
与惰性 属性 初始化和 PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE
一起使用。如果这让您感到困惑,那是因为它令人困惑。
enum UserType:int {
case Master = 1;
case Admin = 2;
case Manager = 3;
}
class User
{
private int $id;
private string $name;
private UserType $userType;
public function __construct()
{
// unset it for lazy initialization (PDO will call __set method instead)
unset($this->userType);
}
public function __set($key, $value)
{
if ($key === 'userType') {
$this->userType = UserType::from($value);
}
}
}
// Tell PDO to call constructor first,
// then try to assign the property if it exists or call magic method __set()
$stmt->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, User::class);
$user = $stmt->fetch();
在构造函数中坚持这样做可能会更容易。然后您可以将该行作为关联数组获取并将其解压缩到构造函数中。
class User
{
private UserType $userType;
public function __construct(private int $id, private string $name, int $userType)
{
$this->userType = UserType::from($userType);
}
}
然后你的 fetchObject()
看起来像:
public function fetchObject($sql, array $args = [], string $class_name = "stdClass"): ?object
{
$stmt = self::$instance->prepare($sql);
$stmt->execute($args ?: null);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
return $row ? new $class_name(...$row) : null;
}
您需要解压缩该行,因为 PDO 无法将值传递给构造函数。
自从枚举功能在 PHP8.1 中发布以来,我想知道如何使用 PDO 从我的数据库中将数据提取到具有 ENUM 属性.
的对象中我有以下枚举:
enum UserType{
case Master: 1;
case Admin: 2;
case Manager: 3;
}
我有以下 class:
class User{
private int $id;
private string $name;
private UserType $userType;
}
每次我尝试执行下面的代码时,我都会收到错误 无法将 int 分配给 属性 User::$userType of type UserType
Database::getInstance()->fetchObject(sql: "SELECT id, name, userType FROM user WHERE id = 1", class_name: User::class);
我想知道是否有办法使上面的代码正常工作,或者在我的代码中实现新枚举功能的最佳方法是什么。
我的 fetchObject 代码:
public function fetchObject($sql, array $args = array(), string $class_name = "stdClass"): mixed
{
$sql = self::$instance->prepare($sql);
if(empty($args)){
$sql->execute();
} else{
$sql->execute($args);
}
$object = $sql->fetchObject($class_name);
$sql->closeCursor();
return $object;
}
fetchObject()
做不到。原因是您不能将 int
分配给 UserType
类型的 属性。您可以使用魔术方法 __set()
,但您不必声明 属性(强烈不推荐)。
您可以将 __set
与惰性 属性 初始化和 PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE
一起使用。如果这让您感到困惑,那是因为它令人困惑。
enum UserType:int {
case Master = 1;
case Admin = 2;
case Manager = 3;
}
class User
{
private int $id;
private string $name;
private UserType $userType;
public function __construct()
{
// unset it for lazy initialization (PDO will call __set method instead)
unset($this->userType);
}
public function __set($key, $value)
{
if ($key === 'userType') {
$this->userType = UserType::from($value);
}
}
}
// Tell PDO to call constructor first,
// then try to assign the property if it exists or call magic method __set()
$stmt->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, User::class);
$user = $stmt->fetch();
在构造函数中坚持这样做可能会更容易。然后您可以将该行作为关联数组获取并将其解压缩到构造函数中。
class User
{
private UserType $userType;
public function __construct(private int $id, private string $name, int $userType)
{
$this->userType = UserType::from($userType);
}
}
然后你的 fetchObject()
看起来像:
public function fetchObject($sql, array $args = [], string $class_name = "stdClass"): ?object
{
$stmt = self::$instance->prepare($sql);
$stmt->execute($args ?: null);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
return $row ? new $class_name(...$row) : null;
}
您需要解压缩该行,因为 PDO 无法将值传递给构造函数。