2つ以上の無関係なクラスをリンクすることを考えることができる唯一の解決策は、を使用すること Annotations
です。
アノテーションはPHPではデフォルトでサポートされていませんが、現在RFC(Request for Comments:Class Metadata)ReflectionClass
でサポートされていますが、時間を曲げることはサポートまたは拒否され、 &Comments
機能 を使用して作成できます。
例このようなクラスが3つある場合
class Data {
/**
*
* @var Cleaner
*/
public $a;
/**
*
* @var Extraset
*/
public $b;
public $runMe;
function __construct() {
$this->runMe = new stdClass();
$this->runMe->action = "RUN";
$this->runMe->name = "ME";
}
}
class Cleaner {
public $varInt = 2;
public $varWelcome = "Hello World";
/**
*
* @var Extraset
*/
public $extra;
}
class Extraset {
public $boo = "This is Crazy";
public $far = array(1,2,3);
}
次に、このようなコードを実行できます
$class = "Data";
$xml = new SimpleXMLElement("<$class />");
getVariablesXML($class, $xml);
header("Content-Type: text/xml");
$xml->asXML('data.xml');
echo $xml->asXML();
出力
<?xml version="1.0"?>
<Data>
<Cleaner name="a">
<varInt type="integer">2</varInt>
<varWelcome type="string">Hello World</varWelcome>
<Extraset name="extra">
<boo type="string">This is Crazy</boo>
<far type="serialized">a:3:{i:0;i:1;i:1;i:2;i:2;i:3;}</far>
</Extraset>
</Cleaner>
<Extraset name="b">
<boo type="string">This is Crazy</boo>
<far type="serialized">a:3:{i:0;i:1;i:1;i:2;i:2;i:3;}</far>
</Extraset>
<runMe type="serialized">O:8:"stdClass":2:{s:6:"action";s:3:"RUN";s:4:"name";s:2:"ME";}</runMe>
</Data>
使用した機能
function getVariablesXML($class, SimpleXMLElement $xml) {
$reflect = new ReflectionClass($class);
foreach ( $reflect->getProperties(ReflectionProperty::IS_PUBLIC) as $property ) {
$propertyReflect = $reflect->getProperty($property->getName());
preg_match("/\@var (.*)/", $propertyReflect->getDocComment(), $match);
$match and $match = trim($match[1]);
if (empty($match)) {
$value = $property->getValue(new $class());
if (is_object($value) || is_array($value)) {
$type = "serialized";
$value = serialize($value);
} else {
$type = gettype($value);
}
$child = $xml->addChild($property->getName(), $value);
$child->addAttribute("type", $type);
} else {
$child = $xml->addChild($match);
$child->addAttribute("name", $property->getName());
if (class_exists($match)) {
getVariablesXML($match, $child);
}
}
}
}