Home » Php » mysql – Dynamically create PHP object based on string

mysql – Dynamically create PHP object based on string

Posted by: admin April 23, 2020 Leave a comment

Questions:

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:

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

…with PHP data types

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.

I was thinking that using:

  1. mysql_fetch_object()
  2. Reading the type attribute
  3. Creating an object with type defined by type attribute

But know of no way to dynamically create a type based on a string. How does one do this?

How to&Answers:

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;
}

Answer:

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);

Answer:

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

Works very well…

Answer:

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);}}

Answer:

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.