PDO:获取类选项,将字段作为数组发送到构造函数


PDO: Fetch class option to send fields to constructor as array

我想知道是否可以将PDO查询的结果优雅地映射到类中的数组成员,而不是将它们作为该对象的公共属性浮动。

假设我有(浓缩的)以下内容:

class DBObject {
    protected
        $record = array();
    function __construct(array $record) {
        if(!empty($record)) {
            $this->loadRecord($record);
        }
    }
}

理想情况下,我希望使用从数据库传递的值数组来调用构造函数,而不是使用__set或任何其他奇怪的方法。因此,使用PDO现有的API将是非常好的。

我目前粗略的get_all函数已经走到了这一步:

static function get_all() {
    $class = get_called_class();
    $results = DB::factory()->query('SELECT * FROM ' . $class . ' ORDER BY ID');
    $results->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, $class);
    return $results;
}

注意:我正在通过PDO运行PHP 5.3和MySQL,并且已经知道使用__set可以解决这个问题,但我明确希望避免使用它,以支持更高性能的东西

您不需要将参数传递给构造函数,就可以使用PDO::FETCH_class生成具有私有成员的类。你可以这样做:

<?php
class Songs
{  
    private $artist;
    private $title;
    public function __construct()
    {  
    }
    public function get_artist()
    {
    return $this->artist;
    }
    public function get_title() 
    {
    return $this->title;
    }
    private function set_artist($artist) 
    {
    $this->artist = $artist;
    }
    private function set_title($title) 
    {
    $this->title = $title;
    }
}

事实上,我是在我建立的一个演示网站上做这件事的。它与PDO::FETCH_CLASS配合使用很好。默认情况下,FETCH_CLASS通过在构造函数之前填充字段来创建对象。可以将其视为绕过构造函数。它将对私人成员这样做。

如果你想把参数传递给构造函数,你可以这样查询:

$obj = $statement->fetchALL(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, 'Songs', $params);

在这种情况下,您的构造函数将如下所示:

public function __construct($params)
{
    $this->artist = $params[0]['artist'];
    $this->title= $params[0]['title'];
}

删除了以前的代码


对,你不能这样做吗:

class DBObject {
    protected $record = array();
    function __construct($record = null) {
        if(null === $record){
            $obj_vars = get_object_vars($this);
            $cls_vars = get_class_vars(get_class($this));
            $this->$record = array_diff_key($obj_vars, $cls_vars);
        }else{
            $this->record = $record;
        }
    }
}

然而,问题是这些价值观仍然可以作为公共成员使用。但它将要做的是将"预定义"(类)成员与实际(对象)成员进行比较。

由于PDO将在对象中创建新成员,因此可以使用array_diff_key来获取"新"成员。

是的,这仍然不会通过构造函数传递它们。

使用magic__set()方法怎么样:

<?php
class MyClass
{
    protected $record = array();
    function __set($name, $value) {
        $this->record[$name] = $value;
    }
}
$pdo = new PDO("mysql:host=localhost;dbname=db", 'user', 'password');
$results = $pdo->query('SELECT * FROM table');
$results->setFetchMode(PDO::FETCH_CLASS, 'MyClass');

PHP将为传入其名称和值的每个不存在的属性调用这个神奇的方法。