3v4l.org

run code in 300+ PHP versions simultaneously
<?php $obj = new stdClass(); $obj->a = 5; $obj->b = 2; $obj->c = 9; $filter = array( 'logic' => 'AND', 'filters' => array( array('field' => 'a', 'operator' => '===', 'value' => 5), array( 'logic' => 'OR', 'filters' => array( array('field' => 'b', 'operator' => '===', 'value' => 6), array('field' => 'c', 'operator' => '<', 'value' => 10), ), ), ), ); function process(string $logic, array $filters, object $obj): bool { // For an AND, all things must be true, so if we're given 5 things, all 5 must be true. // For an OR, only one needs to be true. $targetCount = 'AND' === $logic ? count($filters) : 1; // How many items were true $currentCount = 0; foreach ($filters as $filter) { // The sub-array is a grouping, grab parts, process, and if true, increment our local counter if (array_key_exists('logic', $filter)) { if (process($filter['logic'], $filter['filters'], $obj)) { $currentCount++; } // For a sub-array, don't process anything else continue; } // Grab array items as variables just for ease of use $field = $filter['field']; $operator = $filter['operator']; $value = $filter['value']; // Match on the operator. For lower versions of PHP a switch(true) or just an if could be used, too. $result = match ($operator) { '===' => $obj->$field === $value, '==' => $obj->$field == $value, '>=' => $obj->$field >= $value, '>' => $obj->$field > $value, '<=' => $obj->$field <= $value, '<' => $obj->$field < $value, }; // If success, increment our counter if ($result) { $currentCount++; // If we've reach our target, return success // This could also just be "if process = OR" if ($currentCount === $targetCount) { return true; } } } // See if we met the final condition outside of the loop return $currentCount === $targetCount; } echo process($filter['logic'], $filter['filters'], $obj) ? 'yes' : 'no';
Output for 8.0.8
yes

preferences:
34.14 ms | 407 KiB | 5 Q