代码之家  ›  专栏  ›  技术社区  ›  Mat Kelly

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

  •  44
  • Mat Kelly  · 技术社区  · 16 年前

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

     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选择一行并创建一个类型的对象定义表的类型列,所选行中的其他列将分配给新创建的对象。

    我想用:

    1. mysql_fetch_object()
    2. 读取类型属性
    3. 创建类型由类型属性定义的对象

    但不知道如何根据字符串动态创建类型。怎么做到的?

    5 回复  |  直到 7 年前
        1
  •  100
  •   user229044    15 年前

    但不知道如何根据字符串动态创建类型。怎么做到的?

    您可以非常轻松自然地做到:

    $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;
    }
    
        2
  •  7
  •   roman    16 年前
    $instance = new $classname; // i.e. $type in your case
    

    工作得很好…

        3
  •  7
  •   silkfire thezar    13 年前

    有一个非常好的语法,您可以使用,这是我几个月前学到的,它不依赖于临时变量。下面是一个使用post变量加载特定类的示例:

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

    但是,在您的特定情况下,您可以通过使用PDO来解决它。它有一个提取模式,允许第一列的值是行实例化到的类。

    $sth->fetch(PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE);
    
        4
  •  0
  •   Félix Adriyel Gagnon-Grenier    12 年前

    正如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);}}
    
        5
  •  0
  •   Barry    7 年前

    下面是我在寻找的,当我来到这个线程。使用 {"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;
    

    这种提到物体的方式似乎是可以互换的。我找不到答案,所以在找到解决办法之前,我不得不糊弄它。