【问题标题】:PDO PHP Fetch ClassPDO PHP 获取类
【发布时间】:2026-02-04 01:00:02
【问题描述】:

我正在学习 php 中的 pdo,以便使数据库访问更容易和更有效。我读过的 fetch _class 的一个解释是,对象的属性是在调用构造函数之前设置的。这是什么意思?非常感谢任何方向。

【问题讨论】:

标签: php pdo


【解决方案1】:

这意味着当使用 PDO 将结果返回到自定义对象时,需要设置与查询结果键对应的成员变量。

如:

class User
{
    //Predefine Here
    public $id;
    public $username;
    public $password;
    public $email;
    public $hash;

    public function profileLink()
    {
         return sprintf('<a href="/profile/%s">%s</a>',$this->id,$this->username);
    }
}

$result = $sth->fetchAll(PDO::FETCH_CLASS, "User");
foreach($result as $user)
{
    echo $user->profileLink();
}

这样 PDO 可以将变量设置到其内部范围之外的对象。

如果你的用户类是这样的:

class User
{
}

那么 PDO 将无法从范围之外设置值,因为没有定义属性。

【讨论】:

  • 我猜这意味着如果你用 getter 和 setter、私有变量设置你的类,你就不能使用 PDO::FETCH_CLASS ?
  • 我认为 getter 和 setter 应该被很好地调用(未经测试)
  • 是的,您仍然可以使用私有变量。 FETCH_CLASS 会将结果分配给私有变量。
  • @RobertPitt - 看看 PDO::FETCH_LAZY 常量以及 re: getters/setters - 因为找到了它们分别分配的列。我确信性能会受到影响,因为它都是动态的,最好提前知道你在查询/要求什么,以便其他人使用你的 D.R.Y.稍后编码为 API。
  • 正如@Kris 指出的那样,他们不必公开。我认为根本不需要声明它们,因此您仅声明类的第二个示例就可以正常工作。显然不建议这样做,因为它会使您的代码无法查看,但它确实有效。
【解决方案2】:

假设你有这段代码

<?php
class Foo {
    public $bar;

    public function __construct()
    {
        $this->bar = 1;
    }
}

$stmt = $dbh->prepare("SELECT bar FROM foo");
$stmt->setFetchMode(PDO::FETCH_CLASS, 'Foo'); 
$stmt->execute();
$obj = $stmt->fetch()
?>

$obj 的 bar 属性将设置为“1”,而不是从数据库中检索到的值。

如果您希望将其设置为数据库的结果而不是“1”,您可以将获取模式更改为

$stmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, 'Foo'); 

这会导致在将结果分配给属性之前调用构造函数

【讨论】:

    【解决方案3】:

    而不是使用:FetchAll(PDO::FETCH_CLASS, 'classname') 您可以使用:fetchObject('classname')

    例子:

    class Car extends DatabaseTable {
    
    const TABLE_NAME = 'cars';
    
    // Table Columns
    private $color;
    private $brand;
    private $type;
    
    public function __construct($pdo, $id = false)
    {
        parent::__construct($pdo, TABLE_NAME, $id);
    }
    
    public static function getAll($pdo, $order = 'id') {
        $query =   'SELECT * FROM ' . self::TABLE_NAME . ' 
                    ORDER BY ' . $order;
    
        $statement = $pdo->prepare($query);
    
        $objects = [];
        while ($obj = $statement->fetchObject(self::class, [$pdo])) {
            $objects[$obj->getId()] = $obj;
        }
        return $objects;
    }
    

    父构造函数只设置它的 3 个属性,例如:$this-&gt;id = $id;

    【讨论】:

      【解决方案4】:

      回顾 PDO::FETCH_CLASS,您实际上不需要将变量定义为 public 或 private(从 PHP 7.0 开始),您可以定义一个空类,PHP PDO 会将属性填充为 $Class->属性,即使它们没有定义。

      这非常有用,因为您可以重用具有多个查询的类,这些查询处理同一个表但可能返回不同的列

      【讨论】:

      • 我记得在某处读到过,如果你在一个没有定义相关属性的类上设置/获取实例的属性在 PHP 中要慢得多(我可以'虽然目前找不到链接)。如果处理大量此类对象,则性能影响可能很大。另外,IDE 可能具有类型提示功能,如果没有定义的属性,这些功能将无法运行。
      • 我知道这是一个旧答案,但如果其他人读到它:“但可能返回不同的列” - 这是一个巨大的反模式。当你得到一个类时,你应该知道它有什么属性,或者你需要在你的代码中创建一堆property_exists() 和类似的东西。