Я пытаюсь отфильтровать таблицу MySQL на основе значений в окне множественного выбора, чтобы он возвращал все результаты, чьи значения были выбраны. Например, это мой блок множественного выбора:
<select name="gift[]" id="gift" multiple="multiple" onchange="change()">
<option value="him">Him</option>
<option value="her">Her</option>
<option value="kids">Kids</option>
<option value="teens">Teens</option>
<option value="mothersday">Mothers Day</option>
<option value="fathersday">Fathers Day</option>
<option value="valentines">Valentines Day</option>
<option value="gadgets">Gadgets</option>
<option value="secretsanta">Secret Santa</option>
</select>
Если пользователь выбирает «он» и «гаджеты», он должен вернуть все результаты из таблицы mysql с «ним» или «гаджетами».
Таблица mysql содержит данные для каждого продукта, хранящиеся в одном столбце в виде строки (т. Е. В столбце «подарок» может быть указано его, ее детей, гаджетов или для другой строки это могут быть ее гаджеты. В приведенном выше примере I хочу, чтобы он возвращал обе строки).
Результаты возвращаются AJAX, и я попытался использовать предложение WHERE IN, но не смог заставить его работать. Вот мой код (поле выбора HTML уже указано выше):
AJAX примечание: не полный код для простоты
function change(){
var giftarray = new Array();
$.each($("#gift option:selected"), function(){
giftarray.push($(this).val());
});
var gift = "'" + giftarray.join("','") + "'";
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("product").innerHTML=xmlhttp.responseText;
}
}
var url="results.php"url=url+"&gift="+gift;
xmlhttp.open("GET",url,true);
xmlhttp.send();
}
Results.PHP примечание: не полный код для простоты
$gift=$_GET['gift'];
$gift=str_replace("\\","",$gift);
$sql= "SELECT * FROM $productstable WHERE gift IN ($gift)";
$result = mysql_query($sql) or die ('Unable to run query:'.mysql_error());
while($item = mysql_fetch_array($result))
{
code to view products here
}
<? } mysql_close() ?>
Mysql Таблица и данные Примечание: я только показал столбец подарка, идентификатор и данные для двух строк (надеюсь, это нормально)
CREATE TABLE `products` (
`id` int(255) NOT NULL AUTO_INCREMENT,
`gift` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;
INSERT INTO `products` VALUES(1,'him,her');
INSERT INTO `products` VALUES(2,'him,her,teens,gadgets');
Кажется, это работает, если продукт имеет только одно значение, назначенное ему в таблице mysql, но не работает, когда у него есть несколько. Из того, что я прочитал, я думаю, что могу ошибаться, сохраняя несколько критериев в одном столбце, но не знаю, как это исправить. Большое спасибо.
Вы делаете это неправильно.
Сначала прочитайте о нормализации базы данных. У вас должно быть 3 стола.
type { id, title } for storing him,her,teens,gadgets as rows with unique id
product { id, product_title, ...... } for storing products
product_type {product_id, type_id} to store relation product -> type
Вы должны отправить данные опций в виде массива:
index.php?options[1]=him&options[2]=her&options[3]=kids
И тогда в PHP вы получите это как:
$options = $_GET['options'];
Затем вы можете построить запрос, используя соединение:
$q = "SELECT a.id, a.product_title from product a JOIN product_type b ON a.a=b.product_id WHERE b.type_id IN('".implode("','",$options )."')";
постскриптум
Это всего лишь пример. Очень небезопасно. Вам необходимо подготовить заявления для безопасности, проверить входные данные, создать правильные индексы. Вы можете хранить «тип» в массиве с идентификаторами, но я предпочитаю хранить в базе данных.
Ваш пример неверен со стороны реляционной базы данных. Кроме того, использование LIKE очень неэффективно.
Итак, я нашел решение, но уверен, что это не правильный путь, так как он не очень элегантный. Любые предложения по улучшению приветствуются. Я устанавливаю переменную explode $ gift в массив, а затем создаю несколько операторов OR LIKE с соответствующими символами подстановки. К счастью, в моем множественном окне есть только 9 вариантов, так как этот метод скоро станет утомительным.
КОД:
RESULTS.PHP
$gift=$_GET['gift'];
$gift=str_replace("\\","",$gift);
$gift=str_replace("'","%",$gift);
$gift=explode(",",$gift);
$sql= "SELECT *
FROM $productstable
WHERE gift LIKE '$gift[0]'
OR gift LIKE '$gift[1]'
OR gift LIKE '$gift[2]'
OR gift LIKE '$gift[3]'
OR gift LIKE '$gift[4]'
OR gift LIKE '$gift[5]'
OR gift LIKE '$gift[6]'
OR gift LIKE '$gift[7]'
OR gift LIKE '$gift[8]'
OR gift LIKE '$gift[9]'";
$result = mysql_query($sql) or die ('Unable to run query:'.mysql_error());
while($item = mysql_fetch_array($result))
{
code to view products here
}
<? } mysql_close() ?>
На самом деле этот метод вообще не понравился, так как считалось, что IN должен делать то же самое, но просто не может заставить его работать. Будет ли это иметь негативные последствия со скоростью?
Также собираюсь перекодировать это с помощью PDO позже.