PHP动态获取类构造函数并调用它来创建一个新实例[重复]

Posted

技术标签:

【中文标题】PHP动态获取类构造函数并调用它来创建一个新实例[重复]【英文标题】:PHP Get the class constructor dynamically and call it to create a new instance [duplicate] 【发布时间】:2020-10-03 04:13:49 【问题描述】:

我正在尝试从数据库中获取所有记录,然后使用每个记录中的数据实例化一个新对象:

$stmt = $this->pdo->prepare('SELECT * FROM '.$this->table.' ORDER BY '.$order.' ASC');
    $stmt->execute();
    $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
    if ($results)
        for ($i=0; $i<count($results); ++$i)
            $strValues = '';
            $values = array_values($results[$i]);
            for ($j=0; $j<count($values); ++$j)//Extract the values to pass them as arguments to the constructor below
                if ($j == 0) $strValues .= $values[$j];
                else
                    $strValues .= ',';
                    $strValues .= '"'.$values[$j].'"';
                
            
            eval('$result['.$i.'] = new '.get_class($this->instance).'('.$strValues.');');              
        
    

问题是对象类型可能会有所不同,具体取决于我是在查询 users 还是 labels 数据库,因此对构造函数的调用可能是 new用户(用户 ID、用户名、姓名、姓氏)新标签(标签 ID、姓名、描述、颜色)。上面的代码在 ObjectMapper 类上运行,该类在创建时被分配一个对象类型并将其实例存储在私有 instance 变量中。这样我就可以使用 get_class($this->instance) 获取所需构造函数的名称。

我终于设法使用 eval 使其工作,如图所示,但我读到这不是一个好的做法,我想知道更好和更清洁的方法来做到这一点。

【问题讨论】:

为了将来参考,fetchAll() 最好在您不打算在同一“层”中迭代结果时使用。如果您打算立即对结果集执行迭代处理,那么您应该循环调用fetch() 非常感谢您的帮助!我使用 fetch_all() 因为这是控制器,它为视图准备 $result 数组以在后面的步骤中显示。但是这仍处于早期开发阶段,我的想法是限制查询中的结果不会有太多负载。再次感谢您的回答,我一直走错方向。 【参考方案1】:

这应该可以实现您想要实现的目标。 不要使用eval

PDO 有很多有用的获取模式,它们在此处进行了描述https://phpdelusions.net/pdo/fetch_modes#FETCH_CLASS

$stmt = $this->pdo->prepare('SELECT * FROM '.$this->table.' ORDER BY '.$order.' ASC');
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_CLASS, get_class($this->instance));

附:请记住将表名和$order 变量正确列入白名单。

【讨论】:

以上是关于PHP动态获取类构造函数并调用它来创建一个新实例[重复]的主要内容,如果未能解决你的问题,请参考以下文章

C# 构造函数总结

使用 XmlSerializer.Deserialize 反序列化时何时调用类构造函数?

php面向对象构造函数,析构函数

C# 构造函数总结

JavaScript一个简易枚举类型实现扑克牌

java的jdk动态代理