I have a jQuery script that calls a PHP file that will query a database, then spit the results as XML. The jQuery script takes the XML, parses it and puts it inside an array to draw some charts.
This is the Ajax script:
<script>
var arr={};
$(document).ready(function(){
$.ajax({
type: "POST",
url: "http://myserver.com/query.php",
dataType: "xml",
success: function(xml) {
$(xml).find('item').each(function(index,value){
var data={};
$(this).find('*').each(function(i,v){
if(isNaN(parseFloat($(this).text()))) {
data[$(this).prop('tagName')]=$(this).text();
} else {
data[$(this).prop('tagName')]=parseFloat($(this).text());
}
});
arr[index]=data;
})
DataLoaded();
}
});
});
</script>
I've tested this script using a real query inside the query.php file, and it works fine. Data is retrieved from the DB, shaped into XML format and sent back to JavaScript, where it's correctly processed and played with.
Now... I've found the weirdest of problems when modifying the query: the ajax script doesn't work if the returned XML is too short??
A (simplified) example of the XML output that works fine with the Ajax script:
<results>
<item>
<variable1>value1</variable1>
<variable2>value2</variable2>
<variable3>value3</variable3>
</item>
<item>
<variable1>value4</variable1>
<variable2>value5</variable2>
<variable3>value6</variable3>
</item>
<item>
<variable1>value7</variable1>
<variable2>value8</variable2>
<variable3>value9</variable3>
</item>
<item>
<variable1>value10</variable1>
<variable2>value11</variable2>
<variable3>value12</variable3>
</item>
</results>
An example of the XML output that doesn't work:
<results>
<item>
<variable1>value1</variable1>
<variable2>value2</variable2>
<variable3>value3</variable3>
</item>
<item>
<variable1>value4</variable1>
<variable2>value5</variable2>
<variable3>value6</variable3>
</item>
</results>
For the last case, the PHP is working fine (I can access the PHP file directly from the browser and I see the XML output as shown above), but if I run the HTML file on the server, it'll simply stall forever without ever showing the data.
I've used Chrome debugging tools and Fiddler, and I've seen that my server is apparently returning a "500 Internal Server Errror". But, if I inspect the message in Fiddler, the correct XML output is actually there?!?!
Why is the server returning a 500 Internal Server Error together with the XML data?? And why is it throwing the error ONLY when the output is too short??
I mean, I could understand it having problems with longer datasets... but with shorter ones??
I'm completely at a loss here... any help would be really appreciated!
Edit: Some more info from Fiddler.
The ONLY difference between the response messages seems to be in the header.
Successful case:
HTTP/1.1 200 OK
Date: Mon, 07 Oct 2013 21:50:10 GMT
Server: Apache/2.2.12 (Linux/SUSE)
X-Powered-By: PHP/5.2.14
Content-Length: 4627
Keep-Alive: timeout=15, max=99
Connection: Keep-Alive
Content-Type: text/xml
Failure case:
HTTP/1.0 500 Internal Server Error
Date: Mon, 07 Oct 2013 21:21:22 GMT
Server: Apache/2.2.12 (Linux/SUSE)
X-Powered-By: PHP/5.2.14
Content-Length: 371
Connection: close
Content-Type: text/xml
Below this, both messages contain just the clean XML data as expected!
Update:
PHP code:
<?php
$dbhost = 'myserver.com';
$dbuser = 'login';
$dbpass = 'password';
$dbname = 'DB';
$link = mysql_connect($dbhost, $dbuser, $dbpass) or die("MySQL Error");
mysql_select_db($dbname, $link) or die("DB error");
$sql = "select bla bla bla... working query here";
$result = mysql_query($sql);
function mysql_XML($result, $docName='results', $itemName='item') {
$field = array();
for ($i=0; $i<mysql_num_fields($result); $i++)
$field[$i] = mysql_field_name($result, $i);
// XML document
$dom = new DOMDocument('1.0', 'UTF-8');
$doc = $dom->appendChild($dom->createElement($docName));
for ($i=0; $i<mysql_num_rows($result); $i++) {
$node = $doc->appendChild($dom->createElement($itemName));
for ($b=0; $b<count($field); $b++) {
$textField = $node->appendChild($dom->createElement($field[$b]));
$textField->appendChild($dom->createTextNode(mysql_result($result, $i, $b)));
}
}
// returning XML as text
$dom->formatOutput = true;
return $dom->saveXML();
}
header ('Content-type: text/xml');
echo mysql_XML($result);
$mysql_close();
?>