首页 > 解决方案 > 如何使用 PDO 将数据提取到具有枚举属性的类中?

问题描述

由于枚举功能是在 PHP8.1 中发布的,我想知道如何使用 PDO 从我的数据库中获取数据到具有 ENUM 属性的对象中。

我有以下枚举:

enum UserType{
  case Master: 1;
  case Admin: 2;
  case Manager: 3;
}

我有以下课程:

class User{
  private int $id;
  private string $name;
  private UserType $userType;
}

每次我尝试执行下面的代码时,我都会收到错误Cannot assign int to property 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;
}

标签: phppdophp-8.1

解决方案


你不能用fetchObject(). 原因是您不能分配int给 type 的属性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 无法将值传递给构造函数。


推荐阅读