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动态获取类构造函数并调用它来创建一个新实例[重复]的主要内容,如果未能解决你的问题,请参考以下文章