У меня есть script, который будет запрашивать мою базу данных и должен иметь возможность запрашивать один или все из четырех вариантов. Возможные значения: 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 elseif?
ПРИМЕЧАНИЕ. Я знаю, что я должен использовать 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), если вы не используете фреймворк.