I want to create XML messages for webservice communication. These messages should be created from a pool of reusable elements. Therefore I have created different classes. A "factory" class, that only returns a message class. An element class, that consists of the reusable parts and the message classes that are the blueprints for the desired XML messages.
My code delivers the expected result, but I'm looking for a best practice. Especially a way to get rid of rewriting the same save()
and __construct
method in every of the message classes.
Update:
I have improved my example and moved the
root
property and thesave()
method from the message classes to theElements
class. I also changed the name of the method fromsave
togetMessage
as there is aDOMDocument
method with the same name. Due to these changes I have little less redudant code. I still don't know if it is good practice, particularly to use the "grandparent" methods in the message classes.
// class to create webservice messages class Messages{ private function __construct(){} public static function get($type) { //some error handling if class not exists return new $type; } } // message no.1 class Message_1 extends Elements{ public function __construct() { parent::__construct(); $this->root = $this->createElement("message1"); } public function add_anotherElement(){ $this->root->appendChild($this->add_anotherElementBlock("foo", "bar")); } public function add_element(){ $this->root->appendChild($this->add_someElementBlock("foo", "bar")); } } // message no.2 class Message_2 extends Elements { public function __construct() { parent::__construct(); $this->root = $this->createElement("message2"); } public function add_elements(){ $this->root->appendChild($this->add_anotherElementBlock("foo", "bar")); $this->root->appendChild($this->add_someElementBlock("foo", "bar")); } } // message no.3 class Message_3 extends Elements { public function __construct() { parent::__construct(); $this->root = $this->createElement("message3"); } public function add_element(){ // unique Element $this->root->appendChild($this->createElement("foo", "bar")); } } // reusable elements class Elements extends DOMDocument{ protected $root; protected function add_someElementBlock($foo, $bar) { $node = $this->createElement("root"); $attr = $this->createAttribute("id"); $attr->value = $foo; $node->appendChild($attr); $subnode = $this->createElement("sub",$bar); $node->appendChild($subnode); return $node; } protected function add_anotherElementBlock($foo, $bar) { $node = $this->createElement("anotherRoot"); $subnode = $this->createElement("anotherSubNode",$bar); $attr = $this->createAttribute("anotherAttribute"); $attr->value = $foo; $subnode->appendChild($attr); $node->appendChild($subnode); return $node; } public function getMessage(){ return $this->saveXML($this->root); } } $message1 = Messages::get('Message_1'); $message1->add_element(); $message1->add_anotherElement(); $message2 = Messages::get('Message_2'); $message2->add_elements(); $message3 = Messages::get('Message_3'); $message3->add_element(); //******************************************** echo "<pre>"; print_r(htmlentities($message1->getMessage())); echo "</pre>"; echo "<hr />"; echo "<pre>"; print_r(htmlentities($message2->getMessage())); echo "</pre>"; echo "<hr />"; echo "<pre>"; print_r(htmlentities($message3->getMessage())); echo "</pre>";