[英]Building a better search query php/mysql
我目前正在嘗試將一個非常簡單的搜索表單(所有復選框)放在一起,但遇到將查詢放在一起的問題。 如果選擇了1個位置,1個經驗或僅使用一種語言,則可以返回結果。 如果我選擇任何一個組合,我的結果充其量是最多的。 我的意圖是為用戶返回所有結果:
experience a OR b OR c AND location a OR b OR b OR d AND languages a OR b AND approved
現在,如果我僅選擇一堆位置,沒有其他條件,那么我將不會獲得任何結果。
嘗試通過20多種語言,50多種位置和其他一些要求進行搜索時,我應該查看哪種類型的查詢? 我應該如何去建造它? 我在正確的軌道上嗎?
$adv_search_query = "SELECT
users.*, general.*, languages.*, experience.*
FROM users
LEFT OUTER JOIN languages ON users.user_id = languages.user_id
LEFT OUTER JOIN general ON users.user_id = general.user_id
LEFT OUTER JOIN experience ON users.user_id = experience.user_id
WHERE (";
if(!empty($_POST['location'])) {
foreach($_POST['location'] as $location) {
$location_input = " general.neighborhood LIKE '%" . $location . "%' OR";
}
$adv_search_query .= trim($location_input, 'OR');
$adv_search_query .= ") ";
}
if(!empty($_POST['languages']) && !empty($_POST['location'])) {
$adv_search_query .= "AND (";
}
if(!empty($_POST['languages'])) {
foreach($_POST['languages'] as $language) {
$language_input = " languages." . $language . " = 1 OR";
}
$adv_search_query .= trim($language_input, 'OR');
$adv_search_query .= ") ";
}
if(!empty($_POST['experience']) && !empty($_POST['location'])) {
$adv_search_query .= "AND (";
}
if(!empty($_POST['experience'])) {
foreach($_POST['experience'] as $exp) {
$exp_input = " experience." . $exp . " = 1 OR";
}
$adv_search_query .= trim($exp_input, 'OR');
$adv_search_query .= ") ";
}
if (isset($_POST["approved"])) {
$approved = " users.approved = 1 OR";
} else { $approved = ""; }
if (isset($_POST["pending"])) {
$pending = " users.approved = 2 OR";
} else { $pending = ""; }
if (isset($_POST["incomplete"])) {
$incomplete = " users.approved = 0 OR";
} else { $incomplete = ""; }
if(isset($_POST['approved']) || isset($_POST['pending']) || isset($_POST['incomplete'])) {
$status_input = "AND (" . $approved . " " . $pending . " " . $incomplete . "";
$adv_search_query .= trim($status_input, 'OR');
$adv_search_query .= ") ";
}
$adv_search_query .= "AND users.admin_level = 0";
表
table.users
user_id first_name last_name admin_level user_approved
1 nick jones 0 1
2 johnny rocket 0 1
3 sally fields 0 2
table.general
user_id city state zip neighborhood
1 baltimore maryland 00125 hamsterdam
2 lakeland maine 11542 treemont
3 sonic new york 11763 highville
table.languages
user_id french german italian spanish
1 0 1 0 1
2 0 0 1 1
3 1 1 1 1
table.experience
user_id waldorf kumon homeschooling
1 0 1 0
2 0 0 1
3 1 1 1
首先,請注意,在以下情況下,您的代碼容易受到SQL注入的影響:
general.neighborhood LIKE
部分。
在這種類型的SQL查詢構建中,“ array()”和“ implode”是您的朋友:
$experience_valid_values = array('exp1', 'exp2');
$experience_conditions = array();
if(!empty($_POST['experience'])) {
foreach($_POST['experience'] as $exp) {
if (in_array($exp, $experience_valid_values)) {
$experience_conditions[] = 'experience.' . $exp . '=1';
}
}
}
$language_valid_values = array('english', 'japanese', 'spanish', 'chinese');
$language_conditions = array();
if(!empty($_POST['language'])) {
foreach($_POST['languages'] as $language) {
if (in_array($language, $language_valid_values)) {
$language_conditions[] = 'language.' . $language . '=1';
}
}
}
$conditions = array();
if (!empty($experience_conditions)) {
$conditions[] = '(' . implode(' OR ', $experience_conditions) . ')';
}
if (!empty($language_conditions)) {
$conditions[] = '(' . implode(' OR ', $language_conditions) . ')';
}
$sql = 'SELECT *
FROM users
LEFT OUTER JOIN experience ON users.user_id = experience.user_id
LEFT OUTER JOIN languages ON users.user_id = languages.user_id
WHERE
';
$sql .= implode(' AND ', $conditions);
使用“ array()”和“爆破”將使您的代碼更短,更易於閱讀。 這只是一個簡短的示例,我希望可以給您這個想法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.