基于字符串动态创建PHP对象

时间:2010-02-04 16:32:44

标签: php mysql oop casting

我想基于MySQL数据库中字符串定义的类型在PHP中创建一个对象。数据库表包含以下列的列和示例数据:

 id | type | propertyVal
----+------+-------------
  1 | foo  | lorum
  2 | bar  | ipsum

...使用PHP数据类型

class ParentClass {...}
class Foo extends ParentClass {private $id, $propertyVal; ...}
class Bar extends ParentClass {private $id, $propertyVal; ...} 
//...(more classes)...

只使用一个查询,我想按id选择一行,并创建一个类型的对象,定义表的类型列,并将SELECTed行中的其他列分配给新创建的对象。

我在考虑使用:

  1. mysql_fetch_object()
  2. 阅读类型属性
  3. 使用type attribute
  4. 定义的类型创建对象

    但是知道无法动态创建基于字符串的类型。怎么做到这一点?

5 个答案:

答案 0 :(得分:101)

  

但是知道无法动态创建基于字符串的类型。怎么做到这一点?

你可以很容易和自然地做到这一点:

$type = 'myclass';

$instance = new $type;

如果查询返回关联数组,则可以使用类似的语法分配属性:

// build object
$type = $row['type'];
$instance = new $type;

// remove 'type' so we don't set $instance->type = 'foo' or 'bar'
unset($row['type']);  

// assign properties
foreach ($row as $property => $value) {
   $instance->$property = $value;
}

答案 1 :(得分:8)

你可以使用一种非常简洁的语法,这是我几个月前学到的不依赖于临时变量的语法。这是我使用POST变量加载特定类的示例:

$eb = new ${!${''} = $_POST['entity'] . 'Binding'}();

在您的具体情况下,您可以使用PDO解决它。它有一个获取模式,允许第一列的值成为行实例化的类。

$sth->fetch(PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE);

答案 2 :(得分:7)

$instance = new $classname; // i.e. $type in your case

效果很好......

答案 3 :(得分:0)

正如silkfire所说,这可以通过使用PDO特定模式来实现,所以这是一个例子。使用相同的数据库值和定义的对象:

 id | type | propertyVal
----+------+-------------
  1 | foo  | lorum
  2 | bar  | ipsum

class ParentClass {...}
class Foo extends ParentClass {private $id, $propertyVal; ...}
class Bar extends ParentClass {private $id, $propertyVal; ...} 
//...(more classes)...

使用单个查询(您必须先命名包含类名的字段):

$stmt = $db->prepare('SELECT type,id,propertyVal FROM table WHERE id=1');
$stmt->execute();
$foo = $stmt->fetch(PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE);
var_dump($foo); // $foo is a newly created object of class foo, with properties named like and containing the value of subsequent fields

这很酷,但有一段时间会变得凉爽

$stmt = $db->prepare('SELECT type,id,propertyVal FROM table');
$stmt->execute();
while ($object = $stmt->fetch(PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE))
 {var_dump($object);} // here all desired objects, dynamically constructed accordingly to the first column returned by the query

你可以定义一个构造函数(将数据库中的值分配给属性后调用)来处理那些动态分配的属性,比如用一个字符串替换它的大写值

class foo
 {function __construct ()
   {$this->uper = strtoupper($this->propertyVal);}}

答案 4 :(得分:0)

当我来到这个帖子时,我正在寻找以下内容。使用{"objectName"}(括号)以字符串的形式声明或引用对象名称。

$gameData = new stdClass();
$gameData->location = new stdClass();
$basementstring = "basement";

class tLocation {
    public $description;
}

$gameData->location->{'darkHouse'} = new tLocation;
$gameData->location->{"darkHouse"}->description = "You walkinto a dusty old house";


$gameData->location->{$basementstring} = new tLocation;
$gameData->location->{"basement"}->description = "its really damp down here.";

//var_dump($gameData); 
echo $gameData->location->basement->description;

这种引用对象的方式似乎是可以互换的。我找不到答案,所以我不得不愚弄它直到找到方法。