У меня есть сценарий, который будет запрашивать мою базу данных и должен иметь возможность запрашивать один или все из четырех вариантов. Возможные значения: start sku, end sku (это один параметр, так как должен быть диапазон поиска), созданный и созданный дата. Я знаю, что могу сделать это, используя MANY if..elseif заявления, но я должен думать, что есть лучший и более простой способ. Вот что я имею для кода:
$start =mysql_real_escape_string ($_POST['skuStart']); $end = mysql_real_escape_string($_POST['skuEnd']); $source = mysql_real_escape_string($_POST['source']); $processDate = mysql_real_escape_string($_POST['processDate']); if(!empty($start) && !empty($end) && empty($source) && empty($processDate)){ $result = $conn->query("Select * from inventory where sku >= $start and sku <= $end"); } elseif (empty($start) && empty($end) && !empty($source) && empty($processDate)){ $result = $conn->query("Select * from inventory where created_by = '$source'"); } elseif (empty($start) && empty($end) && empty($source) && !empty($processDate)) { $result = $conn->query("Select * from inventory where date_process = '$processDate'"); } elseif(!empty($start) && !empty($end) && !empty($source) && empty($processDate)){ $result = $conn->query("Select * from inventory where sku >= $start and sku <= $end and created_by = '$source'"); } else { $result = $conn->query("Select * from inventory where sku >= '$start' and sku <= '$end' and created_by = '$source' and date_process = '$processDate'"); } while($row = $result->fetch_assoc()) { $skuArray[$x] = $row['sku']; $isbnArray[$x] = $row['isbn13']; $qtyArray[$x] = $row['quantity']; $defectArray[$x] = $row['defect_id']; $sourceArray[$x] = $row['source_id']; $featureArray[$x] = $row['feature_id']; $locationArray[$x] = $row['location_id']; $processDateArray[$x] = $row['date_process']; $bookTypeArray[$x] = $row['book_type_id']; $createdByArray[$x] = $row['created_by']; $modifiedByArray[$x] = $row['modified_by']; $x++;
Эта очень грубая форма работает, но есть ли способ упростить if ififif?
ПРИМЕЧАНИЕ. Я знаю, что я должен использовать PDO для предотвращения SQL-инъекций, но я еще не полностью изучил это, поэтому я использую это.
Отменив проблемы, о которых вы уже знаете, – переключение на PDO и использование связанных параметров – вы могли бы сделать свой код немного понятным со следующим:
<?php $start = mysql_real_escape_string ($_POST['skuStart']); $end = mysql_real_escape_string($_POST['skuEnd']); $source = mysql_real_escape_string($_POST['source']); $processDate = mysql_real_escape_string($_POST['processDate']); $where = array(); if(!empty($start)) { $where[] = 'sku >= ' . $start; } if(!empty($end)) { $where[] = 'sku <= ' . $end; } if(!empty($source)) { $where[] = 'created_by = \''.$source .'\''; } if(!empty($processDate)) { $where[] = 'date_process = \''.$processDate .'\''; } $query = 'SELECT * FROM inventory'; if(count($where)) { $query .= ' WHERE ' . implode(' AND ', $where); } $result = $conn->query($query); while($row = $result->fetch_assoc()) { $skuArray[$x] = $row['sku']; $isbnArray[$x] = $row['isbn13']; $qtyArray[$x] = $row['quantity']; $defectArray[$x] = $row['defect_id']; $sourceArray[$x] = $row['source_id']; $featureArray[$x] = $row['feature_id']; $locationArray[$x] = $row['location_id']; $processDateArray[$x] = $row['date_process']; $bookTypeArray[$x] = $row['book_type_id']; $createdByArray[$x] = $row['created_by']; $modifiedByArray[$x] = $row['modified_by']; $x++;
<?php $db = new PDO('mysql:host=localhost;dbname=my_db', 'user', 'passwd'); $sql = "SELECT * FROM INVENTORY "; $where = array (); $params = array (); if (! empty($start) && ! empty($end) { $where[] = " sku >= :start AND sku <= :end "; $params['start'] = $start; $params['end'] = $end; } if (! empty($source)) { $where[] = " created_by = :source "; $params['source'] = $source; } if (! empty($processDate)) { $where[] = " date_process = :date_process "; $params['date_process'] = $processDate; } if (! empty($where)) { $sql .= ' WHERE ' . join (' AND ', $where); } $statement = $db->prepare($sql); $statement->execute($params); while ($row = $statement->fetch(PDO::FETCH_ASSOC)) { // ... }
$q = array(); if (!empty($start)) $q[] = "sku >= '$start'"; if (!empty($end)) $q[] = "sku <= '$end'"; #... $q = join(') AND (', $q); $q = "SELECT * FROM inventory WHERE ($q)";
или вы можете сделать следующий шаг:
$params = array( 'skuStart' => "sku >= '##'", 'skuEnd' => "'sku <= '##'", #... ); $q = array(); foreach($params as $k=>$sql) { $v = mysql_real_escape_string($_POST[$k]); if (!empty($v)) { $sql = tr_replace('##', $v, $sql); $q[] = $sql; } } $q = join(') AND (', $q);
И тогда вы можете добавлять типы для проверки, а другие – улучшать ваши метаданные и создавать свою небольшую структуру …
Всякий раз, когда вы чувствуете, что повторяетесь, вы должны проверить существующее решение (библиотеку / фреймворк) или создать свой … DRY .
Вы можете использовать построитель запросов. Например, https://github.com/jstayton/QueryBuilder (сначала основанный в google), если вы не используете какую-либо фреймворк.