У меня есть функция, которая принимает набор параметров, а затем применяет их как условия к SQL-запросу. Однако, пока я предпочитаю массив с одним аргументом, содержащий сами условия:
function searchQuery($params = array()) {
foreach($params as $param => $value) {
switch ($param) {
case 'name':
$query->where('name', $value);
break;
case 'phone':
$query->join('phone');
$query->where('phone', $value);
break;
}
}
}
Вместо этого мой коллега предпочел явно перечислить все аргументы:
function searchQuery($name = '', $phone = '') {
if ($name) {
$query->where('name', $value);
}
if ($phone) {
$query->join('phone');
$query->where('phone', $value);
}
}
Его аргумент состоял в том, что при явном перечислении аргументов поведение функции становится более очевидным - в отличие от необходимости копаться в коде, чтобы выяснить, что это за загадочный аргумент $param
.
Моя проблема заключалась в том, что это становится очень многословным, когда приходится иметь дело со многими аргументами, такими как 10+. Есть ли предпочтительная практика? Мой худший сценарий будет выглядеть примерно так:
searchQuery('', '', '', '', '', '', '', '', '', '', '', '', 'search_query')
источник
foreach
в этом случае ненужно, вы можете использоватьif(!empty($params['name']))
вместоforeach
иswitch
.!empty($params['name'])
для проверки параметров - например, строка «0» будет пустой. Лучше использовать,array_key_exists
чтобы проверить ключ, или,isset
если вам все равноnull
.Ответы:
ИМХО твой коллега подходит для приведенного выше примера. Ваше предпочтение может быть кратким, но также менее читабельным и, следовательно, менее понятным. Задайте вопрос, зачем вообще писать эту функцию, что ваша функция «выводит на стол» - я должен понять, что она делает и как она делает, очень подробно, просто чтобы ее использовать. На его примере, хотя я не программист PHP, я могу видеть достаточно подробностей в объявлении функции, поэтому мне не нужно беспокоиться о ее реализации.
Что касается большего количества аргументов, это обычно считается запахом кода. Как правило, функция пытается сделать слишком много? Если вы обнаружите реальную потребность в большом количестве аргументов, скорее всего, они каким-то образом связаны и принадлежат одной или нескольким структурам или классам (возможно, даже массиву связанных элементов, таких как строки в адресе). Однако передача неструктурированного массива ничего не делает для устранения запахов кода.
источник
where
аргументов, один дляjoin
спецификаторов и т. д. При правильном присвоении им имен это все равно будет самодокументироваться.Мой ответ более или менее зависит от языка.
Если единственной целью группировки аргументов в сложной структуре данных (таблица, запись, словарь, объект ...) является передача их целиком в функцию, лучше избегать этого. Это добавляет бесполезный слой сложности и делает ваше намерение неясным.
Если сгруппированные аргументы сами по себе имеют значение, то этот уровень сложности помогает понять весь дизайн: вместо этого назовите его слоем абстракции.
Возможно, вы обнаружите, что вместо дюжины отдельных аргументов или одного большого массива лучше всего использовать два или три аргумента, каждый из которых группирует коррелированные данные.
источник
В вашем случае я бы предпочел метод вашего коллеги. Если вы писали модели, а я использовал ваши модели, чтобы развиваться над ними. Я вижу подпись метода вашего коллеги и могу использовать его немедленно.
Пока я должен был бы пройти через реализацию вашей
searchQuery
функции, чтобы увидеть, какие параметры ожидаются вашей функцией.Я бы предпочел ваш подход только в том случае, если
searchQuery
поиск ограничен только одной таблицей, поэтому объединений не будет. В этом случае моя функция будет выглядеть так:Итак, я сразу знаю, что элементы массива на самом деле являются именами столбцов конкретной таблицы, которую класс, имеющий этот метод, представляет в вашем коде.
источник
Сделайте и то, и другое.
array_merge
допускает явный список в верхней части функции, как нравится вашему коллеге, при этом параметры остаются громоздкими, как вы предпочитаете.Я также настоятельно рекомендую использовать предложение @ chiborg из комментариев к вопросу - гораздо яснее, что вы намереваетесь.
источник
Также вы можете передать строку, похожую на строку запроса, и использовать
parse_str
(потому что кажется, что вы используете PHP, но другие решения, вероятно, доступны на других языках), чтобы обработать ее в массив внутри метода:и называть это как
Вы можете использовать
http_build_query
для преобразования из ассоциативного массива в строку (наоборотparse_str
).источник