php 基于字符串动态创建PHP对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2201335/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Dynamically create PHP object based on string
提问by Mat Kelly
I would like to create an object in PHP based on a type defined by a string in a MySQL database. The database table has columns and sample data of:
我想基于由 MySQL 数据库中的字符串定义的类型在 PHP 中创建一个对象。数据库表具有以下列和示例数据:
id | type | propertyVal
----+------+-------------
1 | foo | lorum
2 | bar | ipsum
...with PHP data types
...使用 PHP 数据类型
class ParentClass {...}
class Foo extends ParentClass {private $id, $propertyVal; ...}
class Bar extends ParentClass {private $id, $propertyVal; ...}
//...(more classes)...
Using only one query, I would like to SELECT a row by id and create an object of the type define the table's type column with other columns in the SELECTed row being assigned to the newly created object.
仅使用一个查询,我想按 id SELECT 一行并创建一个定义表类型列的对象,SELECTed 行中的其他列被分配给新创建的对象。
I was thinking that using:
我在想使用:
mysql_fetch_object()- Reading the type attribute
- Creating an object with type defined by type attribute
mysql_fetch_object()- 读取类型属性
- 创建具有由 type 属性定义的类型的对象
But know of no way to dynamically create a type based on a string. How does one do this?
但是不知道有没有办法根据字符串动态创建类型。如何做到这一点?
回答by meagar
But know of no way to dynamically create a type based on a string. How does one do this?
但是不知道有没有办法根据字符串动态创建类型。如何做到这一点?
You can do it quite easily and naturally:
您可以轻松自然地做到这一点:
$type = 'myclass';
$instance = new $type;
If your query is returning an associative array, you can assign properties using similar syntax:
如果您的查询返回关联数组,您可以使用类似的语法分配属性:
// 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;
}
回答by silkfire
There's a very neat syntax you can use that I learned about a couple of months ago that does not rely on a temporary variable. Here's an example where I use a POST variable to load a specific class:
您可以使用一种非常简洁的语法,我在几个月前了解到它不依赖于临时变量。这是我使用 POST 变量加载特定类的示例:
$eb = new ${!${''} = $_POST['entity'] . 'Binding'}();
In your specific case though, you would be able to solve it by using PDO. It has a fetch mode that allows the first column's value to be the class the row instantiates into.
但是,在您的特定情况下,您可以使用 PDO 来解决它。它有一个获取模式,允许第一列的值是行实例化的类。
$sth->fetch(PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE);
回答by roman
$instance = new $classname; // i.e. $type in your case
Works very well...
效果很好...
回答by Félix Gagnon-Grenier
as silkfire says, this can be achieved by using PDO specific modes, so here is an example. Using your same database values and defined objects:
正如 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)...
with a single query (you must name the field containing the class name first):
使用单个查询(您必须首先命名包含类名的字段):
$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
this is cool but it gets cooler with a while
这很酷,但一段时间后会变凉
$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
you can define a constructor (which will be called after the values from database are assigned to properties) to work on those dynamically assigned properties, say by replacing a string with it's uppercased value
您可以定义一个构造函数(将在数据库中的值分配给属性后调用)来处理那些动态分配的属性,例如用大写的值替换字符串
class foo
{function __construct ()
{$this->uper = strtoupper($this->propertyVal);}}
回答by Peter S McIntyre
Below is what I was looking for when I came to this thread. use {"objectName"}(brackets) to declare or reference the object name in the form of a string.
以下是我来到此线程时正在寻找的内容。使用{"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;
This way of referring to the object seems to be interchangeable. I couldn't find the answer so i had to fool around with it Until I found a way.
这种引用对象的方式似乎可以互换。我找不到答案,所以我不得不四处寻找答案,直到找到方法为止。

