Ядрото на проблема ви изглежда е фактът, че заобикаляте колоната DetailName
в единични кавички:"'DetailName'='"
когато всичко, което трябва да бъде, е "DetailName='"
От гледна точка на сигурността бих искал да отбележа, че функцията mysql_escape_string()
който използвате, за да принудите въвеждането да бъде удобен за mysql, е стар и пълен с дупки в сигурността. Вместо това бих препоръчал да използвате много по-безопасната реализация:mysql_real_escape_string()
. Примерите за код по-долу използват по-новата, по-безопасна функция.
Отделно от тези проблеми обаче, бих препоръчал да използвате малко по-различен подход, който ще бъде по-лесен за четене и много по-лесен за управление в дългосрочен план.
Като начало бих препоръчал да използвате едно и също име във всички квадратчета за отметка и да използвате DetailName като стойност, а не като ключ:
<td>
<input name="criteria[]" type="checkbox" id="Buffet" value="Buffet" />
<strong><label for="Buffet">Buffet</label></strong>
</td>
<td>
<input name="criteria[]" type="checkbox" id="Breakfast" value="Breakfast" />
<strong><label for="Breakfast">Breakfast</label></strong>
</td>
<td>
<input name="criteria[]" type="checkbox" id="BYOB" value="BYOB" />
<strong><label for="BYOB">BYOB</label></strong>
</td>
След това, използвайки стойностите на вашите входове, а не ключовете, вече можем да генерираме нашата клауза. Много ефективно:
// Runs mysql_real_escape_string() on every value encountered.
$clean_criteria = array_map('mysql_real_escape_string', $_REQUEST['criteria']);
// Convert the array into a string.
$criteria = implode("','", $clean_criteria);
И накрая, в заявката си бих препоръчал да използвате IN
оператор, а не OR
оператор за ефективност и четливост:
SELECT
tblLocations.CityID, tblRestaurants.RestName, tblLocations.Street, tblLocations.Phone, tblLocations.Price, tblLocations.Rating, tblDetails.DetailName
FROM
(
tblRestaurants
INNER JOIN
tblLocations ON tblRestaurants.RestID = tblLocations.RestID
)
INNER JOIN
(
tblLocDet
INNER JOIN
tblDetails ON tblLocDet.DetailID = tblDetails.DetailID
) ON tblLocations.LocationID = tblLocDet.LocID
WHERE tblLocations.CityID='16' AND tblDetails.DetailName IN ($criteria)
ORDER BY tblRestaurants.RestName ASC
Ето цялата PHP страна на нещата, комбинираща модификациите, които предлагам с вашата логика:
<?php
require "congig.php";
if(!empty($_POST['criteria'])) { // empty() checks if the value is set before checking if it's empty.
foreach($_POST['criteria'] as $key=>$value){
// Runs mysql_real_escape_string() on every value encountered.
$clean_criteria = array_map('mysql_real_escape_string', $_REQUEST['criteria']);
// Convert the array into a string.
$criteria = implode("','", $clean_criteria);
}
$rs = mysql_query("
SELECT
tblLocations.CityID, tblRestaurants.RestName, tblLocations.Street, tblLocations.Phone, tblLocations.Price, tblLocations.Rating, tblDetails.DetailName
FROM
(
tblRestaurants
INNER JOIN
tblLocations ON tblRestaurants.RestID = tblLocations.RestID
)
INNER JOIN
(
tblLocDet
INNER JOIN
tblDetails ON tblLocDet.DetailID = tblDetails.DetailID
) ON tblLocations.LocationID = tblLocDet.LocID
WHERE tblLocations.CityID='16' AND tblDetails.DetailName IN ($criteria)
ORDER BY tblRestaurants.RestName ASC
");
if(!$rs) {
echo "Cannot parse query";
} else if(mysql_num_rows($rs) == 0) {
echo "No records found";
} else {
echo "<table id=\"myTable\" table width=\"710\" class=\"beautifuldata\" align=\"Left\" cellspacing=\"0\">\n";
echo "<thead>\n<tr>";
echo "<th>PLACE</th>";
echo "<th>ADDRESS</th>";
echo "<th>PHONE</th>";
echo "<th>PRICE</th>";
echo "<th>RATING</th>";
echo "</tr>\n</thead>\n";
while($row = mysql_fetch_array($rs)) {
echo"<tr>
<td><strong><a href='$row[RestPage]'>$row[RestName]</a></strong></td>
<td>$row[Address]</td>
<td>$row[Phone]</td>
<td>$row[Price]</td>
<td>$row[Rating]</td>
</tr>\n";
}
echo "</table><br />\n";
}
}