web-dev-qa-db-ja.com

動的に作成PHP文字列に基づいたオブジェクト

MySQLデータベースの文字列で定義されたタイプに基づいてPHPにオブジェクトを作成したいと思います。データベーステーブルには次の列とサンプルデータがあります。

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

... with PHPデータ型

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

1つのクエリのみを使用して、IDで行を選択し、新しく作成されたオブジェクトに割り当てられているSELECT行の他の列とともにテーブルの型列を定義する型のオブジェクトを作成します。

私はそれを使用すると考えていました:

  1. mysql_fetch_object()
  2. タイプ属性の読み取り
  3. タイプ属性で定義されたタイプを持つオブジェクトの作成

ただし、文字列に基づいて型を動的に作成する方法はありません。これをどのように行うのですか?

44
Mat Kelly

ただし、文字列に基づいて型を動的に作成する方法はありません。これをどのように行うのですか?

非常に簡単かつ自然にできます:

$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;
}
101
meagar

一時変数に依存しない、数か月前に学んだ非常にきちんとした構文があります。 POST変数を使用して特定のクラスをロードする例を次に示します。

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

ただし、特定のケースでは、PDOを使用して解決できます。最初の列の値を、行がインスタンス化するクラスにすることができるフェッチモードがあります。

$sth->fetch(PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE);
8
silkfire
$instance = new $classname; // i.e. $type in your case

とてもうまくいきます...

7
roman

以下は、このスレッドに来たときに探していたものです。使用する {"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;

このオブジェクトの参照方法は互換性があるようです。私は答えを見つけることができなかったので、道を見つけるまで私はそれをあざける必要がありました。

0

silkfireが言うように、これはPDO固有のモードを使用することで実現できるため、ここに例を示します。同じデータベース値と定義済みオブジェクトを使用する:

 id |タイプ| propertyVal 
 ---- + ------ + ------------- 
 1 | foo | lorum 
 2 |バー| ipsum 
 
 class ParentClass {...} 
 class FooはParentClass {private $ id、$ propertyVal;を拡張します。 ...} 
 class BarはParentClassを拡張します{private $ id、$ propertyVal; ...} 
 // ...(その他のクラス)... 

単一のクエリ(最初にクラス名を含むフィールドに名前を付ける必要があります):

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