Я создаю поисковую систему для школьного проекта, предназначенную для того, чтобы пользователи могли просматривать большую базу данных школ, и я настроил ее так, чтобы на одной странице пользователь мог отмечать определенные флажки и что после нажатия кнопки отправки пользователю будет возвращен список школ, соответствующих тому, что было отмечено.
Пользователь может искать школы по всей стране по ряду параметров:
- Тип школы (средняя школа, средняя школа, профессиональная школа, университет и т. Д.)
- Статус школы (частная или государственная)
- Город
- Состояние
- и т.д.
По моему вопросу я сосредоточусь только на той части, которая относится к типам школ, поскольку позже я смогу применить логику с другими элементами формы, которые функционируют аналогично.
Для типов школ наряду с рядом других элементов формы я решил использовать флажки, так что, например, если пользователь хочет, чтобы поиск возвращал как средние, так и средние школы, ему нужно будет только отметить оба флажки "средняя школа" и "средняя школа".
Таким образом, это подразумевает использование в моем поиске операторов OR
, чтобы, например, у меня был SQL-запрос, подобный следующему:
SELECT schools.schoolId, schools.schoolName, villages.villageName FROM schools, villages
WHERE schools.villageId = villages.villageId
И здесь я бы поставил условие, чтобы по запросу возвращалась только информация, относящаяся к средним, средним и профессиональным школам:
AND (schools.schoolType = "MiddleSchool" OR schools.schoolType = "HighSchool" OR schools.schoolType = "TradeSchool")
Именно из-за конструкции этого утверждения у меня возникают проблемы.
В действительности, поскольку типы школ могут меняться по мере развития базы данных, я не могу жестко кодировать конструкцию своего запроса и не хочу.
Я использую PHP для генерации запроса на основе результатов формы.
Чтобы сгенерировать список всех доступных типов школ, я прочитал все существующие типы школ из базы данных (MySQL), используя запрос DISTINCT
. Я использую это для составления списка всех доступных типов школ, которые я использую для создания формы поиска.
Поэтому я должен использовать аналогичный метод для сравнения результатов формы с базой данных. Это означает, что на моей странице результатов, чтобы увидеть, какие флажки были отмечены, мне нужно увидеть, какие флажки могли существовать в данный момент. форма была отправлена, поэтому я еще раз прочитал все доступные типы из базы данных: (некоторый код обрезан, это только тот запрос, который я использую, который, как я знаю, работает, но это только для контекста)
try
{
$pdo = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$req_sql_type_school = "SELECT DISTINCT schoolType AS types FROM schools";
$res_type_schools = $pdo->query($req_sql_type_school);
$res_type_schools->setFetchMode(PDO::FETCH_ASSOC);
} catch (PDOException $e)
{
die("Could not connect to the database $dbname :" . $e->getMessage());
}
После этого я перебираю результаты запроса, чтобы создать массив типов школ: (Я знаю, это тоже работает, но опять же, это только для контекста)
$arrayTypes = array();
while ($row = $res_type_schools->fetch())
{
$arrayTypes[]=$row['types'];
}
Тогда вот где я борюсь. Именно в этот момент я должен создать оператор «И ...» в начале запроса, о котором я упоминал выше, который был:
SELECT schools.schoolId, schools.schoolName, villages.villageName FROM schools, villages
WHERE schools.villageId = villages.villageId
Чтобы увидеть, был ли пользователь помечен или нет, я перебираю массив, чтобы проверить, отмечен ли соответствующий флажок. Для этого вот код, который я написал. Примечание: basictext()
просто форматирует строку в формат, который я использовал для значений моего флажка, то есть строки только в нижнем регистре без пробелов и без акцентов):
foreach($arrayTypes as $arr)
{
if(isSet($_GET[basictext($arr)]))
{
echo "[x] Type ".$arr." <br/>";
}
else
{
echo "[ ] Type ".$arr." <br/>";
}
}
Это позволяет мне проверять, какие типы были проверены пользователем в форме поиска.
Однако я не знаю, как перевести это в оператор AND, который я хотел, а именно:
AND (schools.schoolType = "MiddleSchool" OR schools.schoolType = "HighSchool" OR schools.schoolType = "TradeSchool")
Я думал о том, чтобы поместить каждый тип в круглые скобки и отделить каждый тип с помощью OR
, и писать только в круглых скобках, если тип действительно проверен.
Это привело к чему-то вроде этого:
AND ((schools.schoolType = 'MiddleSchool') OR () OR () OR (schools.schoolType = 'HighSchool') OR () OR () OR ())
Само собой разумеется, это было очень уродливо, и это также не работало, таким образом, я консервировал это. Проблема в том, что я не знаю, сколько «проверенных типов» может быть, поэтому немного сложнее создать правильный запрос.
Одно из решений, о которых я подумал при написании этого, - поместить каждый «действительный» тип в массив, а затем использовать этот массив, длину которого я бы тогда знал. Тогда я смогу создать ожидаемый оператор AND, потому что тогда у меня будет определенное количество отмеченных флажков, и это также позволит мне полностью игнорировать не отмеченные значения. Как вы думаете, это будет работать?