Исходный код
if ($category) {$zapros="where category='$category'"; $f[1]=1;}
if ($group) {
if ($f[1]==1) {$zapros.=" and idu='$row[0]'";}
else {$zapros="where idu='$row[0]'";}
$f[2]=1;
}
if ($type) {
if (($f[1]==1)||($f[2]==1)) {$zapros.=" and type='$type'";}
else {$zapros="where type='$type'";}
$f[3]=1;
}
if ($format) {
if (($f[1]==1)||($f[2]==1)||($f[3]==1)) {$zapros.=" and format='$format'";}
else {$zapros="where format='$format'";}
$f[4]=1;
}
if ($curlang) {
if (($f[1]==1)||($f[2]==1)||($f[3]==1)||($f[4]==1)) {$zapros.=" and (lang='$curlang' or lang='all')";}
else {$zapros="where (lang='$curlang' or lang='all')";}
$f[5]=1;
}
Что не так в исходном коде
Здесь сразу несколько проблем различной степени тяжести.
- Однородная обработка данных выполняется без массивов и циклов, что приводит к ненужным переменным и проверкам. Конкретно здесь цикл здесь ни к чему, так как входные данные раскиданы по разным переменным, а вот массив для выходных данных очень даже пригодится.
- Смешаны ответственности по формированию каждого отдельного условия, всего набора условий, а также оператора
where
. - Дублируется реализация по каждому отдельному условию:
$zapros.=" and idu='$row[0]'"
и$zapros="where idu='$row[0]'"
. - Отсутствует защита от SQL инъекций.
- Имеет место неявная связь между
$group
и$row[0]
, которая может испортить жизнь при будущих доработках алгоритма. - Неудачно выбрано название переменной
$zapros
: во-первых, по-русски, во-вторых, в ней формируется не сам sql-запрос, а только where clause от него (по крайней мере, в данном участке кода).
Как улучшить исходный код
function makeConditionField($field_name, $field_value, $op = '=') {
return $field_value ? "$field_name $op '$field_value'" : null;
}
function makeConditionLang($lang) {
return $lang ? "(lang='$lang' or lang='all')" : null;
}
function joinConditionsAnd($conditions) {
return implode(' and ', array_filter($conditions));
}
$conditions[] = makeConditionField('category', $category);
$conditions[] = makeConditionField('idu', $idu);
$conditions[] = makeConditionField('type', $type);
$conditions[] = makeConditionField('format', $format);
$conditions[] = makeConditionLang($lang);
$conditions_str = joinConditionsAnd($conditions);
$where = empty($conditions_str) ? '' : "where $conditions_str";