如果我有课:
class ExampleClass {
private $thing1;
private $thing2;
}
我可以在mysqli_result对象上使用fetch_object('ExampleClass')
来创建ExampleClass的实例。使用此方法,将设置ExampleClass的私有属性,前提是查询具有相同名称的列。
除了这些属性之外,还将为查询中的任何其他列添加其他公共属性。有什么方法可以避免这种情况吗?我在php documentation for fetch_object中找不到任何相关内容。
如果我使用像这样的构造函数设置ExampleClass
function __construct($properties = []) {
foreach ($properties as $key => $value)
if (property_exists($this, $key))
$this->$key = $value;
}
我可以使用fetch_assoc而不是fetch_object从结果集中获取行,然后使用生成的数组作为参数创建一个新的ExampleClass。这实现了我的目标,但我希望能有更直接的东西。
答案 0 :(得分:0)
对于我的一个项目,我已经构建了一个类似的系统。
所有类都派生自基本的抽象Object类,其中包括cloneInstance()
方法。然后,在具体的实现类中,我只是想使用它('我假设$ pdo在某种程度上可以在这里访问,为了简洁):
请注意cloneInstance()
使用反射来检查目标实例是否实际上具有euqlly命名属性($drfl->hasProperty()
)。
abstract class Object {
protected function cloneInstance($obj) {
if (is_object($obj)) {
$srfl = new ReflectionObject($obj);
$drfl = new ReflectionObject($this);
$sprops = $srfl->getProperties();
foreach ($sprops as $sprop) {
$sprop->setAccessible(true);
$name = $sprop->getName();
if ($drfl->hasProperty($name)) {
$value = $sprop->getValue($obj);
$propDest = $drfl->getProperty($name);
$propDest->setAccessible(true);
$propDest->setValue($this,$value);
}
}
}
return $this;
}
class MyAutomaticClass extends Object {
// static loader
public static function load($id) {
$result = null;
$sql = 'SELECT * FROM mytable WHERE id=:id';
$stmt = $pdo->prepare($sql, array(':id' => $id));
$list = $stmt->fetchAll(PDO::FETCH_OBJ);
if (count($list)) {
$result = new MyAutomaticClass($list[0]);
}
return $result;
}
// constructor makes use of base Objects cloning feature
public function __construct($obj=null) {
if (is_object($obj)) {
$this->cloneInstance($obj);
}
}
}