PHP:createTextNode作为对象

I have a script that reads XML tags and prints it on my page. Some items are links (without HTML tags) so I made a function that adds HTML link tags to it. However, the links are rendered as strings and not as HTML.

I know its because I used createTextNode, So i need something that returns it as an object and not as a string.

Heres my code

function get_feeds() {
    $feeds = array(
        array(
            'name' => 'Agenda',
            'url' => 'http://www.beleefdokkum.nl//pages/rss.aspx?type=agenda',
            'get' => array('title', 'description', 'link'),
            'scope' => array(1, 10)
        ),
        array(
            'name' => 'News',
            'url' => 'http://www.beleefdokkum.nl//pages/rss.aspx?type=nieuws',
            'get' => array('title', 'description', 'link'),
            'scope' => array(1, 10)
        ),
        array(
            'name' => 'Social media',
            'url' => 'http://api.twitter.com/1/statuses/user_timeline.rss?screen_name=NOFriesland',
            'get' => array('description'),
            'scope' => array(1, 10)
        )
    );

    $result = new DOMDocument();

    function linkify($text) {
        $text = preg_replace('/(https?:\/\/\S+)/', '<a href="\1" class="preg-links">\1</a>', $text);
        $text = preg_replace('/(^|\s)@(\w+)/', '\1@<a href="http://twitter.com/\2" class="preg-links">\2</a>', $text);
        $text = preg_replace('/(^|\s)#(\w+)/', '\1#<a href="http://search.twitter.com/search?q=%23\2" class="preg-links">\2</a>', $text);
        return $text;
    }

    foreach ($feeds as $feed) {
        $xml = new DOMDocument();
        $xml->load($feed['url']);
        $frame = $result->createElement('div');
        $frame->setAttribute('class', 'feed_frame');
        $result->appendChild($frame);
        $name = $result->createElement('h1', $feed['name']);
        $name->setAttribute('class', 'feed_name');
        $frame->appendChild($name);
        $content = $result->createElement('div');
        $content->setAttribute('class', 'feed_content');
        $frame->appendChild($content);
        for ($i = $feed['scope'][0]; $i < $feed['scope'][1]; $i++) {
            $item = $result->createElement('span');
            $item->setAttribute('class', 'feed_item');
            $content->appendChild($item);
            foreach ($feed['get'] as $get) {
                $object = $result->createElement('p');
                $text = $result->createTextNode(linkify($xml->getElementsByTagName($get)->item($i)->nodeValue));
                $object->appendChild($text);
                $object->setAttribute('class', 'feed_'.$get);
                $item->appendChild($object);
            }
        }
    }
    return $result->saveHTML();
}

There might be other ways, but I would solve it by creating both text nodes and anchors as you're performing the regular expression matching:

$node = $dom->createElement('p');
linkify($doc, $node, 'T1 @test T2 #test T3 http://www.stackoverflow.com T4');

The linkify() function takes an existing node and creates text nodes and anchors based on the given string.

function linkify($dom, $node, $text)
{
    // we combine all possible patterns in one expression
    $re = '/(https?:\/\/\S+)|(?:^|\s)@(\w+)|(?:^|\s)#(\w+)/';
    // we capture pattern offsets
    $flags = PREG_SET_ORDER | PREG_OFFSET_CAPTURE;

    $offset = 0;
    if (preg_match_all($re, $text, $matches, $flags)) {
        foreach ($matches as $match) {
            // set start and end markers of the matched pattern
            $start = $match[0][1];
            $end = $match[0][1] + strlen($match[0][0]);
            // process each pattern based on the resulting matches
            if (isset($match[3])) { // Twitter hash
                $start += 2; // skip space and #
                $url = 'http://search.twitter.com/search?q=' . 
                    urlencode("#{$match[3][0]}");
                $anchor = anchor($dom, $url, $match[3][0]);
            } elseif (isset($match[2])) { // Twitter user
                $start += 2;
                $url = 'http://twitter.com/' . urlencode($match[2][0]);
                $anchor = anchor($dom, $url, $match[2][0]);
            } else { // standard url
                $anchor = anchor($dom, $match[1][0], $match[1][0]);
            }

            if ($start > $offset) {
                // we have text in between previous match (or start) and here
                $str = substr($text, $offset, $start - $offset);
                $node->appendChild($dom->createTextNode($str));
            }
            // insert the new anchor
            $node->appendChild($anchor);
            // keep track of last match marker
            $offset = $end;
        }
        // add last text node
        $node->appendChild($dom->createTextNode(substr($text, $offset)));
    }
}

This would be the output when you run ->saveHTML():

<p>
  T1 
   @<a href="http://twitter.com/datibbaW" class="preg-links">datibbaW</a> 
  T2
   #<a href="http://search.twitter.com/search?q=%23test" class="preg-links">test</a>
  T3 
   <a href="http://www.stackoverflow.com" class="preg-links">http://www.stackoverflow.com</a>
   T4</p>

I'm using a convenience function to create anchors:

function anchor($dom, $url, $text)
{
    $anchor = $dom->createElement('a', $text);
    $anchor->setAttribute('href', $url);
    $anchor->setAttribute('class', 'preg-links');

    return $anchor;
}