简体   繁体   中英

Passing variables from methods to methods inside a class

I need to build a very complex xml sheet with hundreds of different channels. To avoid repeating code and end up with 6k lines, I have coded two methods, one creating a contentless channel, and an other one creating a populated channel. here is my code, I'll explain what my problem is below :

class create_xml {

    private $xml_file;
    private $title;
    private $content;
    private $date;
    private $backlink;
    private $filename = "feed.xml";


    public function __construct($title, $content, $date, $backlink) {
            $this->title = $title;
            $this->content = $content;
            $this->date = $date;
            $this->backlink = $backlink;
            $this->xml_file = new DOMDocument('1.0', 'utf-8');
    }

    //Creates a new channel without any content
    private function cless_channel($chan_name) {
        $$chan_name = $this->xml_file->createElement($chan_name);
        $$chan_name = $this->xml_file->appendChild($$this->chan_name);
    }

    //Creates a populated channel
    private function popu_channel($chan_name, $content, $parent) {
        $sub_chan = $this->xml_file->createElement($chan_name);
        $sub_chan = $$parent->appendChild($title);
        $sub_content = $this->xml_file->createTextNode($content);
        $sub_content = $sub_chan->appendChild($sub_content);
    }

    private function gen_xml() {            

        $this->cless_channel("channelroot");
        $this->popu_channel("channel_one", "a random content", "channelroot");
    }

    public function save_xml() {
        $this->gen_xml();
        //Saves xml document
        return $xml_file->save($filename);
    }

    public function return_xml() {
        $this->gen_xml();
        //Returns xml content as str
        return $xml_file->saveXML();
    }
}

Alright so basicaly I'm calling both methods $this->cless_channel(), and $this->popu_channel(), I'm using dynamic variable to pass the variable name from one method to the other but that obviously does not work. What I need is to mix between class attributes and dynamic variables to be able to pass variables from methods to other methods. Note that this code only shows two nodes but I'll have many more and I don't think declaring as many variables as there will be channels is very good practice, so I'm also looking for a way to avoid that but I suppose I can do this with arrays. So far get this to work would be a great start. I have a tried a bunch of different things, none of them worked so I'm not even going to bother showing them off.

Thank you in advance for any sort of help you can provide.

Not quite sure if I understand the question correctly but just giving it a try.
This variable variables thingy just won't work. It would be possible to return an array that contains all those elements you would otherwise try to access through variable variables.
Or you could turn the process around and pass a callback to the skeleton method which would "ask" the callback if there's something to be added to the otherwise empty/default element.
But if speed isn't the topmost priority just let the method that creates the empty skeleton return the (outermost) element it has created and let the method that populates some of the (empty) elements with additional data "grab" those elements it "wants to" alter/augment/change.
Something along the line of:

<?php
$foo = new Foo;
$foo->skeleton('A');
$foo->populate1('B', 'lalala'); // this doesn't necessarily have to be in the same class
echo $foo->asxml();

class Foo {
    private $root;

    public function __construct() {
        $doc = new DOMDocument;
        $doc->preserveWhiteSpace = false;
        $doc->formatOutput = true;
        $this->root = $doc->appendChild( $doc->createElement('root') );
    }

    public function skeleton($name) {
        $container = $this->root->ownerDocument->createElement($name);  

        // for brevity adding raw xml to the container element
        $fragment = $this->root->ownerDocument->createDocumentFragment();
        $fragment->appendXML("<foo/><bar/><baz/><data><point /><point /><point /></data>");
        $container->appendChild($fragment);

        return $this->root->appendChild($container);
    }

    public function populate1($name, $point1) {
        $container = $this->skeleton($name);

        $xpath = new DOMXPath($container->ownerDocument);
        foreach( $xpath->query('./data/point[1]', $container) as $p) { // can be only one, but anyway...
            $p->appendChild( $container->ownerDocument->createTextNode($point1) );
        }
    }

    public function asxml() {
        return $this->root->ownerDocument->saveXML();
    }
}

prints

<?xml version="1.0"?>
<root>
  <A>
    <foo/>
    <bar/>
    <baz/>
    <data>
      <point/>
      <point/>
      <point/>
    </data>
  </A>
  <B>
    <foo/>
    <bar/>
    <baz/>
    <data>
      <point>lalala</point>
      <point/>
      <point/>
    </data>
  </B>
</root>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM