Если задача извлечения данных по набору параметров из базы, то запрос можно конструировать, безо всяких многоэтажных условий.
Примерно так:
$filters = array();
$values = array();
foreach(array("user_id","city","age","name") as $key) {
if (isset($_GET[$key])) {
$filters []= "$key = ?";
$values []= $_GET[$key];
}
}
$sth = $dbh->prepare("SELECT * FROM users WHERE ".implode(" AND ", $filters);
$sth->execute($values);
Тут для всех указанных запросов накапливаются условия фильтра и значения в два массива, один затем через AND используется в WHERE, а второй передаётся при выполнении запроса.
Но реальные сложные проекты так не делают. У них может быть ORM, кэширование и много всякой другой магии, цель которой - увеличить скорость выполнения запросов и уменьшить лишнюю активность. Ну и базы данных могут бычть частично или полностью быть совсем не SQL.