Динамически создавать PHP, если условие - PullRequest
0 голосов
/ 06 апреля 2019

У меня есть форма с несколькими полями, по которой пользователь может искать. Как динамически записать условие if на основе полей, выбранных пользователем?

например. У меня есть 3 поля следующим образом:

$categoryId = $_REQUEST['category_id'];
$locationId = $_REQUEST['location_id'];
$statusId = $_REQUEST['status_id'];

Если пользователь выбрал category_id, location_id и status_id, то оператор my if должен выглядеть следующим образом:

if (!empty($categoryId) && !empty($locationId) && !empty($statusId)) {
  if (isInTaxonomy($recordId, $categoryId) && isInTaxonomy($recordId, $locationId) && isInTaxonomy($recordId, $statusId) {
    // Do something
  }
}

если пользователь выбрал category_id и location_id, то my if statmeent будет выглядеть следующим образом:

if (!empty($categoryId) && !empty($locationId)) {
  if (isInTaxonomy($recordId, $categoryId) && isInTaxonomy($recordId, $locationId) {
    // Do something
  }
}

если пользователь выбрал только category_id, тогда my if statmeent будет выглядеть следующим образом:

if (!empty($categoryId)) {
  if (isInTaxonomy($recordId, $categoryId)) {
    // Do something
  }
}

Как вы видите, мне приходится реализовывать каждую возможную комбинацию полей, которую пользователь может выбрать для построения всех различных условий.

Я думал о том, чтобы сделать что-то вроде следующего, но это просто даст мне строку, и я не хочу использовать eval для ее выполнения:

$filter = [(!empty($categoryId) ? '(isInTaxonomy($recordId, $categoryId))' : ''),
         (!empty($locationId) ? '(isInTaxonomy($recordId, $locationId))' : '')];

$condition = implode(' && ', array_filter($filter));

if (eval("return $condition;")) {
   // Do something
}

Есть ли способ динамически генерировать все условия, используя более краткий код, не прибегая к Eval?

Ответы [ 3 ]

1 голос
/ 07 апреля 2019

Полагаю, вы можете использовать следующий подход - определить доступные ключи и перебрать их, а перебрать - собрать некоторые данные, например, так:

$keys = ['category_id', 'location_id', 'status_id'];

$operationAllowed = true;
foreach ($keys as $key) {
    if (!empty($_REQUEST[$key])) {
        $operationAllowed = $operationAllowed && isInTaxonomy($recordId, $_REQUEST[$key]);
    }
}
0 голосов
/ 07 апреля 2019

Вы можете добавить их в массив и зациклить массив (или сохранить их в массиве и зациклить там).

$categoryId = $_REQUEST['category_id'];
$locationId = $_REQUEST['location_id'];
$statusId = $_REQUEST['status_id'];
// This can be done in different ways, I kept your "style" since you may have other reasons to extract the values
$arr =[$categoryId, $locationId, $statusId];

$arr = array_filter($arr); // remove empty values
$return[] = false; // set 0 key to false. First iteration will overwrite it
foreach($arr as $key => $val){
    if (isInTaxonomy($recordId, $val)) {
         $return[$key] = true;
    }
}

if(array_diff($return, [true])) {
    // Don't do something (?)
}else{
    // Do something
    // (All is true)
} 

Поскольку я использую array_filter, он не будет проверять пустое значение, которое вернет false.

Я переосмыслил свой код.
Если бы все три были пустыми, тогда мой предыдущий код вернул бы true, что было бы неправильно (я думаю).
Поэтому вместо этого я начинаю с утверждения false и добавляю true / false в массив, а затем после цикла я вижу, получил ли я какие-либо ложные возвращаемые значения с помощью array_diff.
Array_diff удалит все true, если возвращаемый массив имеет какие-либо значения, то хотя бы одно значение в цикле было false.

0 голосов
/ 07 апреля 2019

Это дает те же результаты:

$categoryId = $_REQUEST['category_id'];
$locationId = $_REQUEST['location_id'];
$statusId = $_REQUEST['status_id'];

if( (empty($categoryId) || isInTaxonomy($recordId, $categoryId)) &&
    (empty($locationId) || isInTaxonomy($recordId, $locationId)) &&
    (empty($statusId)   || isInTaxonomy($recordId, $statusId))) {
    // Do Something
}

Он разделен строками, каждая переменная является строкой.Если переменная пуста, строка оценивается как true (без проверки isInTaxonomy) и переходит к следующей, если переменная не пустая, то проверяется второе условие, оценивается isInTaxonomy, если оно true, проверка продолжается на следующей строке, если она false, она останавливается.


Редактировать: вы также можете использовать этот подход в цикле for

$args = ['category_id', 'location_id', 'status_id'];

$valid = true;
foreach ($args as $arg) {
    $valid &= empty($_REQUEST[$arg]) || isInTaxonomy($recordId, $_REQUEST[$arg]);
}

if($valid) {
    // Do Something
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...