выбрать фильтр таблицы по строке запроса php

Итак, я некоторое время пытался заставить это работать, но должно быть лучшее решение, чем то, о чем я думаю. Я новичок в php/mysql, поэтому не знаю, как сделать следующее:

У меня есть окно поиска, содержащее раскрывающиеся списки для страны, штата, города. Теперь, если пользователь выбирает только страну и нажимает на поиск, ему нужно отфильтровать выбор только по стране и показать все остальное.

if(!empty($_REQUEST['city']))
    $city = $_REQUEST['city'];
else
    $city= "%";

if(!empty($_REQUEST['state']))
    $state= $_REQUEST['state'];
else
    $state= "%";

if(!empty($_REQUEST['country']))
    $country= $_REQUEST['country'];

select * from table where country = $country and state = $state and city = $city

проблема в том, что эти столбцы представляют собой целые числа, поэтому я не могу использовать «%» для их фильтрации. Я надеюсь, что смог объяснить это, любая помощь более чем приветствуется. заранее спасибо


person Andres    schedule 10.05.2011    source источник


Ответы (4)


  1. Если вы не хотите ограничивать столбец, просто исключите его из запроса.
  2. никогда не вставляйте строку из $_REQUEST непосредственно в строку запроса — классический недостаток SQL-инъекций.
  3. вы, вероятно, захотите ввести какое-то ограничение, чтобы запрос не возвращал каждый результат в вашей базе данных.

пример:

<?php
$conditions = array();

if(!empty($_REQUEST['city']))
    $conditions[] = "city = " . mysql_real_escape_string($_REQUEST['city']);

if(!empty($_REQUEST['state']))
    $conditions[] = "state = " . mysql_real_escape_string($_REQUEST['state']);

if(!empty($_REQUEST['country']))
    $conditions[] = "country = " . mysql_real_escape_string($_REQUEST['country']);

$sql = 'select * from table ';
if(!empty($conditions))
    $sql .= ' where '. implode(' AND ', $conditions);
$sql .= ' LIMIT 1000';
person Frank Farmer    schedule 10.05.2011
comment
единственный комментарий, который у меня есть, это использовать (int) вместо mysql_real_escape_string. Он утверждает, что поля являются целыми числами. Кроме того, кажется, у нас была одна и та же идея ;-) - person Joshua - Pendo; 10.05.2011
comment
@Frank Farmer, хорошо, и ты полностью опередил меня, хотел бы я печатать быстрее ... :) @PENDO, у тебя тоже есть хороший метод, хотя я думаю, и я могу ошибаться, когда имеешь дело с целыми числами и MySQL вы должны опустить одинарные кавычки вокруг самого значения, одинарные кавычки предназначены для символов и строк, а не для целых чисел. - person hypervisor666; 10.05.2011
comment
просто вещь, к которой я привык с годами ... она работает отлично, но ваша точка зрения принята, я должен «отучить» себя цитировать целые числа. - person Joshua - Pendo; 10.05.2011
comment
Целочисленные кавычки не слишком вредят в mysql (хотя я тоже не сразу осознаю какие-либо преимущества); mysql выполняет кастинг по мере необходимости (в этом случае он даже выдает предупреждение?). Тем не менее, вы должны быть более осторожны с некоторыми другими базами данных — postgres версии 8.3 и выше отказываются автоматически приводить целые числа в кавычках при сравнении со столбцами int. - person Frank Farmer; 10.05.2011
comment
Это прекрасно работает, но по какой-то странной причине возвращает все города, даже если я их фильтрую. - person Andres; 12.05.2011
comment
неважно, у меня была неправильная переменная запроса. спасибо отлично работает!! - person Andres; 13.05.2011

Возможно, вы захотите написать несколько строк запроса, одну только для страны, одну для штата и страны и одну для города, штата и страны. В качестве альтернативы вы можете собрать строку запроса на основе различных параметров, с которыми вам нужно работать.

Пример:

if(isset() || isset() || isset() ) //make sure at least one is set
{
  $query_string = "SELECT * FROM table WHERE ";

  if(isset($_REQUEST['country']))
  {
      $country = $_REQUEST['country'];
      $query_string .= " country = $country";
  }

  if(isset($_REQUEST['state']))
  {
      $state = $_REQUEST['state'];
      $query_string .= " state = $state";
  }

  if(isset($_REQUEST['city']))
  {
      $city = $_REQUEST['city'];
      $query_string .= " city = $city";
  }
}
else
{
    //Else, if none are set, just select all the entries if no specifications were made
    $query_string = "SELECT * FROM table";
}

  //Then run your query...

Таким образом, в английском языке первое, что вы делаете, это проверяете свои параметры, чтобы убедиться, что у вас есть с чем работать, прежде чем пытаться объединить пустые переменные вместе. Затем вы создаете базовую строку запроса (если у нас есть параметры) и оставляете ее открытой, чтобы мы могли добавить любые параметры, которые вам нужны. Затем проверьте каждый параметр и, если он установлен, соедините этот параметр с концом строки запроса. Наконец, обработайте запрос, отправив его на сервер SQL.

Удачи!

h

person hypervisor666    schedule 10.05.2011

Вот мои предложения.

Я даю вам ответ, хотя у вас их уже три. Я думаю, мой может быть проще для кодовых глаз.

  1. не используйте необработанное значение $_REQUEST, так как вполне вероятно, что пользователь может отравить вашу базу данных, передав ей поддельные $_REQUEST данные. Хотя могут быть лучшие способы сделать это, помните о команде "mysql_real_escape_string($string)".
  2. Распространенный метод решения этой проблемы, который я видел, описан ниже. (Идея взрыва, по сути. Фрэнк Фармер делает то же самое в своем.)

-

$__searchWheres = array(); //Where we'll store each requirement used later
foreach( array('city','state','country') as $_searchOption) {
   if ( ! empty( $_REQUEST[$_searchOption] ) ) {
       $__searchWheres[] = $_searchOption . '= "' . mysql_real_escape_string( $_REQUEST[$_searchOption] ) . '"';
   }
}
$__query = 'select * from table' . (count($__searchWheres) > 0 ? ' WHERE ' . implode(' AND ',$__searchWheres) : '');  //Implode idea also used by Frank Farmer
//Select from the table, but only add the 'WHERE' key and where data if we have it.
mysql_query($__query);
person SoreThumb    schedule 10.05.2011

person    schedule
comment
кажется, я немного опоздал :D - person Joshua - Pendo; 10.05.2011