我做了一些測試,我發現,你的代碼在結構上存在一些問題。您應該始終將代碼格式正確,以便更快地找到錯誤和問題。我對代碼進行了格式化,發現嵌套和查詢存在一些問題。
我還想告訴你,你有一個非常嚴重的SQL注入問題,我通過使用預處理語句和一小段額外的preg_replace
來解決查詢和表中的所有不需要的字符。你應該完全去學習一些關於防止SQL注入的知識。但是也有一些專門討論這個問題在這裏巨大的話題,我做了這些物品的清單給你:
這裏是我格式化和固定的代碼。我已經通過使用無參數,空參數,數據庫中不存在的值以及數據庫中存在的值對其進行了測試。每一個返回相應的值:三個第一個返回null,而真正的查詢返回true;在這種情況下,如果找不到,則返回「沒有酒店可用」或者如果找到這些酒店的列表。如果數據庫查詢失敗,它將默認返回null,然後返回「找不到酒店」。
我很抱歉改變代碼佈局一點點,隨意編輯它,只要你喜歡,這取決於你。我強烈建議使用適當的格式(可能是因爲您的代碼編輯器)。
的index.php
<?php
$language = "en";
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Hotel Selection</title>
</head>
<body>
<select id="hotelselection">
<option value="null">No hotels available</option>
</select>
<script>
function selecthotel(str) {
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
}else{
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function(){
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("hotelselection").innerHTML = xmlhttp.responseText;
}
}
if (typeof(str) == "undefined" || str == null) {
str = "";
}
xmlhttp.open("GET", "run.php?location=" + str + "&language=<?php echo($language); ?>", true);
xmlhttp.send();
}
selecthotel();
</script>
</body>
</html>
run.php
<?php
$phrases = array(
"en_error_db" => "No hotels available...",
"en_choose_hotel" => "Choose a hotel..."
);
$link_id = mysqli_connect("localhost", "", "", "");
if (mysqli_connect_errno($link_id)) {
die("Error occurred when attempting to connect to database (" . mysqli_connect_errno() . ": " . mysqli_connect_error() . ").");
error_log("Error occurred when attempting to connect to database (" . mysqli_connect_errno() . ": " . mysqli_connect_error() . ").");
exit(1);
}
$language_raw = isset($_GET["language"]) ? $_GET["language"] : "en";
$location_raw = isset($_GET['location']) ? $_GET["location"] : "";
$language = preg_replace("/[^\w.-]/", "", $language_raw);
$location = preg_replace("/[^\w.-]/", "", $location_raw);
if (empty($location)) {
$query = "SELECT * FROM `eshop_articles` WHERE `category` = '/WEBSITE/SEARCHENGINE/HOTELS' ORDER BY `appearance` ASC";
}else{
$query = "SELECT * FROM `eshop_articles` WHERE `category` = '/WEBSITE/SEARCHENGINE/HOTELS' AND `short_description` = ? ORDER BY `appearance` ASC";
}
if ($stmt = mysqli_prepare($link_id, $query)) {
if (!empty($location)) {
mysqli_stmt_bind_param($stmt, "s", $location);
}
mysqli_stmt_execute($stmt);
// Thanks to Bruce Martin on php.net for the SELECT * via _fetch (http://www.php.net/manual/en/mysqli-stmt.fetch.php#107034)
$metaResults = mysqli_stmt_result_metadata($stmt);
$fields = mysqli_fetch_fields($metaResults);
$statementParams = "";
foreach ($fields as $field) {
$statementParams .= (empty($statementParams) ? "\$column['" . $field->name . "']" : ", \$column['" . $field->name . "']");
}
$statment = "\$stmt->bind_result($statementParams);";
eval($statment);
print('<option value="0">' . $phrases[(isset($phrases[$language . "_choose_hotel"]) ? $language : "en") . "_choose_hotel"] . '</option>');
while (mysqli_stmt_fetch($stmt)) {
print('<option value="' . $column['appearance'] . '">' . $column['title'] . '</option>');
}
exit(1);
}else{
print('<option value="0">' . $phrases[(isset($phrases[$language . "_choose_hotel"]) ? $language : "en") . "_error_db"] . '</option>');
error_log("The script was unable to prepare a MySQLi statement (" . $query . ").");
exit(1);
}
?>
我切換到MySQLi數據庫擴展,而不是你deprecated MySQL extension。它不應該通過PHP錯誤日誌返回PHP錯誤。如果可能,我強烈建議切換到MySQL PDO。這非常簡單,容易,在我看來效果更好!
另外,關於您的XMLHttpRequest/ActiveXObject用法的說明:如果您希望能夠支持IE 5,請爲其創建一個類並在客戶端使用該瀏覽器時加載該腳本,否則使用jQuery Ajax,這非常易於使用,你不需要擔心查詢字符串等。使用ActiveXObject腳本的原因是IE 5不支持jQuery,儘管存在已知的安全問題,但它仍然是一種常見的瀏覽器。 IE 5被舊計算機,一些銀行,辦公室和其他未查看安全細節的企業所使用。
希望這對你有所幫助。
爲什麼不使用$ .ajax()...? – Alex
在IE 5中不支持jQuery Ajax,雖然這是一個很大的安全風險,但這很常見,這就是爲什麼使用XMLHttpRequest和ActiveXObject創建Ajax函數的類是必不可少的。 – ascx
我有IE 11.仍然沒有工作 – GeorgeGeorgitsis