データベースにクエリを実行し、結果を XML として吐き出す PHP ファイルを呼び出す jQuery スクリプトがあります。jQuery スクリプトは XML を取得して解析し、それを配列内に配置してグラフを描画します。
これは Ajax スクリプトです。
<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>
query.php ファイル内で実際のクエリを使用してこのスクリプトをテストしたところ、問題なく動作しました。データは DB から取得され、XML 形式に整形されて JavaScript に送り返され、そこで正しく処理されて再生されます。
さて...クエリを変更するときに最も奇妙な問題を発見しました.返されたXMLが短すぎるとajaxスクリプトが機能しません??
Ajax スクリプトで正常に動作する XML 出力の (簡略化された) 例:
<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>
動作しないXML 出力の例:
<results>
<item>
<variable1>value1</variable1>
<variable2>value2</variable2>
<variable3>value3</variable3>
</item>
<item>
<variable1>value4</variable1>
<variable2>value5</variable2>
<variable3>value6</variable3>
</item>
</results>
最後のケースでは、PHP は正常に動作しています (ブラウザーから PHP ファイルに直接アクセスでき、上記のように XML 出力が表示されます)。ただし、サーバーで HTML ファイルを実行すると、何もせずに永久に停止します。データを表示します。
Chrome デバッグ ツールと Fiddler を使用しましたが、サーバーが「500 内部サーバー エラー」を返しているようです。しかし、Fiddler でメッセージを調べると、実際には正しい XML 出力が表示されている?!?!
サーバーが XML データと共に 500 Internal Server Error を返すのはなぜですか?? 出力が短すぎる場合にのみエラーがスローされるのはなぜですか??
つまり、長いデータセットでは問題が発生することは理解できましたが、短いデータセットでは??
私はここで完全に途方に暮れています...どんな助けも本当に感謝しています!
編集: Fiddler からの詳細情報。
応答メッセージの唯一の違いはヘッダーにあるようです。
成功例:
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
失敗例:
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
これより下では、両方のメッセージに予想どおりクリーンな XML データのみが含まれています。
アップデート:
PHP コード:
<?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();
?>