3

When building XML in PHP, is it quicker to build a string, then echo out the string or to use the XML functions that php gives you? Currently I'm doing the following:

UPDATED to better code snippet:

$searchParam = mysql_real_escape_string($_POST['s']);
$search = new Search($searchParam);

if($search->retResult()>0){
    $xmlRes = $search->buildXML();
}
else {
    $xmlRes = '<status>no results</status>';
}

$xml = "<?xml version=\"1.0\"?>";
$xml.="<results>";
$xml.=$xmlRes;
$xml.="</results>"

header ("content-type: text/xml");
header ("content-length: ".strlen($xml));
echo($xml);


class Search {
private $num;
private $q;

function __construct($s){
    $this->q = mysql_query('select * from foo_table where name = "'.$s.'"');
    $this->num = mysql_num_rows($this->q);
}

function retResult(){
    return $this->num;
}

function buildXML(){
    $xml ='<status>success</status>';
    $xml.='<items>';
    while($row = mysql_fetch_object($this->q)){
        $xml.='<item>';
        $desTag = '<info><![CDATA[';
        foreach ($row as $key => $current){
            if($key=='fob'){
                //do something with current
                $b = mysql_query('select blah from dddd where id ='.$current);
                $a = mysql_fetch_array($b);
                $xml.='<'.$key.'>'.$a['blah'].'</'.$key.'>';
            }
            else if($key =='this' || $key=='that'){
                $desTag = ' '.$current;
            }
            else {
                $xml.='<'.$key.'>'.$current.'</'.$key.'>';
            }   
        }
        $desTag.= ']]></info>';
        $xml.=$desTag;
        $xml.='</item>';
    }
    $xml.='</items>';
    return $xml;
}

}

Is there a faster way of building the xml? I get to about 2000 items and it starts to slow down..

Thanks in advance!

4
  • Your code snippet doesn't really make much sense (a row contains multiple items?) and contains typos. Please post an actual code snippet, reduced for readability. Commented Apr 15, 2010 at 18:03
  • updated with better code snippet. Thanks. Commented Apr 15, 2010 at 18:36
  • 1
    (Just a note) - also make sure that your SQL queries are performing well Commented Apr 15, 2010 at 18:40
  • yea checked all queries, they took under .05 seconds, which was initially what I thought the problem was. Thanks though Commented Apr 15, 2010 at 18:50

5 Answers 5

6

Use the xml parser. Remember when you concatenate a string, you have to reallocate the WHOLE STRING on every concatenation.

For small strings, string is is probably faster, but in your case definitely use the XML functions.

Sign up to request clarification or add additional context in comments.

2 Comments

Using the XML PEAR tree.php file (downloadable at their site)? or something else?
I highly doubt that a concatenation assignment (.=) reallocates memory on every use. Searching the php-dev's mailing list may turn up some stuff about it.
2

I don't see that you're making no attempt to escape the text before concatenating it. Which means that sooner or later you're going to generate something that is almost-but-not-quite XML, and which will be rejected by any conforming parser.

Use a library (XMLWriter is probably more performant than others, but I haven't done XML with PHP).

4 Comments

this was just a trimmed down version to try and get an idea of what a better way of doing it would be.. XML Writer is better than DomDocument?
@Frederico - correctness beats speed every time. If you know the XML spec well enough to concatenate correctly, then more power to you. I don't, and I've been working with XML for a dozen years.
anded up re-writing with XMLWriter and found a few things to increase speed. Thanks!
1

You have a SQL query inside of a loop, which is usually quite a bad idea. Even if each query takes half a millisecond to complete, it's still a whole second just to execute those 2000 queries.

What you need to do is post the two queries in a new question so that someone can show you how to turn them into a single query using a JOIN.

Database stuff usually largely outweighs any kind of micro-optimization. Whether you use string concatenation or XMLWriter doesn't matter when you're executing several thousand queries.

Comments

0

try to echo in each iteration (put the echo $xml before the while loop ends, and reset $xml at the beggining), should be quicker

3 Comments

in that case using xml functions wouldn't help - xml data structures are more complex than strings
Why? Your code keeps no state for each item. Do you need to calculate something after creating / during the 'xml string'?
yea, during the creation, other elements need to be calculated out, also to pass down with the output of the XML, i do a strlen to add in the header, so the reader knows what to expect. Helps with download on the other end.
0

That code snippet doesn't make a lot of sense, please post some actual code, reduced for readability.

A faster version of the code you posted would be

$xml = '';
while ($row =  mysql_fetch_row($result))
{
    $xml .= '<items><test>' . implode('</test><test>', $row) . '</test></items>';
}

In general, using mysql_fetch_object() is slightly slower than the other options.

Perhaps what you were trying to do was something like this:

$xml = '<items>';
while ($row =  mysql_fetch_assoc($result))
{
    $xml .= '<item>';
    foreach ($row as $k => $v)
    {
        $xml .= '<' . $k . '>' . htmlspecialchars($v) . '</' . $v . '>';
    }
    $xml .= '</item>';
}
$xml .= '</items>';

As mentionned elsewhere, you have to escape the values unless you're 100% sure there will never be any special character such as "<" ">" or "&". This also applies to $k actually. In that kind of script, it is also generally more performant to use XML attributes instead of nodes.

With so little information about your goal, all we can do is micro-optimize. Perhaps you should work on the principles behind your script instead? For instance, do you really have to generate 2000 items. Can you cache the result, can you cache anything? Can't you paginate the result, etc...

Quick word about using PHP's XML libraries, XMLWriter will generally be slightly slower than using string manipulation. Everything else will be noticeably slower than strings.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.