Dynamically create PHP object based on string

前端 未结 5 2268
不思量自难忘°
不思量自难忘° 2020-11-27 15:17

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:



        
相关标签:
5条回答
  • 2020-11-27 15:24

    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;
    }
    
    0 讨论(0)
  • 2020-11-27 15:26

    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.

    $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.

    0 讨论(0)
  • 2020-11-27 15:27

    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:

     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);}}
    
    0 讨论(0)
  • 2020-11-27 15:34
    $instance = new $classname; // i.e. $type in your case
    

    Works very well...

    0 讨论(0)
  • 2020-11-27 15:46

    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:

    $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.

    $sth->fetch(PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE);
    
    0 讨论(0)
提交回复
热议问题