48 votes

Créer dynamiquement en PHP objet basé sur la chaîne de

Je voudrais créer un objet en PHP basé sur un type défini par une chaîne de caractères dans une base de données MySQL. La table de base de données a des colonnes et des données de l'échantillon de:

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

...avec PHP types de données

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

L'aide d'une seule requête, je voudrais SÉLECTIONNER une ligne par code et de créer un objet du type de définir la table type de la colonne avec les autres colonnes de la ligne Sélectionnée être affecté à l'objet nouvellement créé.

Je pensais que l'utilisation de:

  1. mysql_fetch_object()
  2. La lecture de l'attribut type
  3. La création d'un objet de type défini par l'attribut de type de

Mais connais pas la façon de créer dynamiquement un type basé sur une chaîne de caractères. Comment fait-on cela?

112voto

meagar Points 85475

Mais connais pas la façon de créer dynamiquement un type basé sur une chaîne de caractères. Comment fait-on cela?

Vous pouvez le faire très facilement et naturellement:

$type = 'myclass';

$instance = new $type;

Si votre requête retourne un tableau associatif, vous pouvez attribuer des propriétés en utilisant la même syntaxe:

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

10voto

silkfire Points 5745

Il y a une très soigné syntaxe que vous pouvez utiliser que j'ai appris il y a quelques mois qui ne repose pas sur une variable temporaire. Voici un exemple où j'utilise une variable POST pour charger une classe spécifique:

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

Dans votre cas particulier, vous serait en mesure de le résoudre en utilisant PDO. Il dispose d'un mode de lecture qui permet à la première valeur de la colonne à la classe de la ligne instancie dans.

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

8voto

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

Fonctionne très bien...

0voto

comme silkfire dit, cela peut être réalisé en utilisant PDO modes spécifiques, voici donc un exemple. À l'aide de votre base de données des valeurs et des objets définis par:

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

la classe Myclass {...}
la classe Foo s'étend Myclass {private $id, $propertyVal; ...}
classe de Barre s'étend Myclass {private $id, $propertyVal; ...} 
//...(autres classes)...

avec une seule requête (vous devez donner le nom du champ contenant le nom de la classe de première):

$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

c'est cool, mais il fait plus froid avec un tout

$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

vous pouvez définir un constructeur (qui sera appelé après les valeurs de la base de données sont affectées à des propriétés) pour travailler sur ces attribuée dynamiquement les propriétés, par exemple pour remplacer une chaîne dont il est en majuscule valeur

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X