使用存储在数组中的比较运算符

时间:2011-12-17 08:14:43

标签: php

我有以下示例数组:

$comparisons = array(
    0 => array(
        'method'    => 'productTotalQuantity',
        'operator'  => '>=',
        'value'     => '2'
    ),
    1 => array(
        'method'    => 'productTotalWeight',
        'operator'  => '<=',
        'value'     => '10'
    )
);

我发明了这种数组结构,因此可以根据需要进行更改。 我试图以某种方式评估操作键,以便我可以实现以下几点:

foreach ($comparisons as $comparison) {
    $value = $this->$comparison['method']($product);
    // E.g. $value = $this->productTotalQuantity($product)
    // $value could = 4

    if ($value $comparison['operator'] $comparison['value']) {
        // Comparison successful
        $matches[] = TRUE;
    }
}

if (count($matches) == count($comparisons)) {
    // All comparisons were successful. Apply the discount.
}

如果你有时间,如何解析这个数组的完整代码示例将非常有用。我已经连续工作了大约20个小时,并且认为我要把头撞在砖墙上。如果您熟悉Magento,我会尝试模仿促销中“购物车价格规则”条件的功能。

3 个答案:

答案 0 :(得分:4)

&#34;翻译&#34;从字符串到实际操作的操作大多是脏的或邪恶的:-)你需要很多条件代码(if-else)或eval(但是每个人都知道:eval是邪恶的^^)

我会使用面向对象的方法,因为PHP确实支持面向对象(我不知道确切的php语法,它已经有一段时间;-))并且我给你伪代码来强制执行这些想法:

class AbstractComparator {
   boolean static compare($operand1, $operand2);   
}

class EqualsComparator extends AbstractComparator {
   @Override
   boolean static compare($operand1, $operand2) {
      return ($operand1 == $operand2);
   }
}

// Now use one of the subclasses in your datastructure
$comparisons = array(
0 => array(
    'method'    => 'productTotalQuantity',
    'operator'  => EqualsComparator,
    'value'     => '2'
),
1 => array(
    'method'    => 'productTotalWeight',
    'operator'  => SmallerThanComparator,
    'value'     => '10'
)
);

$allComparisonsSuccessful = true;
foreach ($comparisons as $comparison) {
   $value = $comparison['operator'].equals($product);
    // Use the AND operator... full predicate is only true if all elements are true
   $allComparisonsSuccessful = $allComparisonsSuccessful && $value;
}

答案 1 :(得分:1)

对于eval()来说,这将是一项轻松的工作。不幸的是,关于何时使用eval()的重要规则是:从不这样做

所以你可以引入像这样的方法

function parseComparison($comparison)
{
    list($methodValue,$operator,$value);
    switch ($operator)
    {
        case '>=': return $methodValue >= $value;
        case '<=': return $methodValue <= $value;
        case '>':  return $methodValue >  $value;
        case '<':  return $methodValue <  $value;
        default: return false;
    }
}

答案 2 :(得分:0)

<?php

$ge = function($a, $b) {return($a >= $b);};
$le = function($a, $b) {return($a <= $b);};

$comparisons = array(
    array(
        'method'    => 'productTotalQuantity',
        'operator'  => $ge,
        'value'     => 2
    ),
    array(
        'method'    => 'productTotalWeight',
        'operator'  => $le,
        'value'     => 10
    )
);

// finds out if discount should be applied in this price range
function discount_finder($myval, $comparisons) {
    $discount = TRUE;
    foreach($comparisons as $comp) {
        if (!$comp['operator']($myval, $comp['value'])) {
            $discount = FALSE;
            $break;
        }
    }
    return $discount;
}

$discount = discount_finder(1, $comparisons);
if ($discount == TRUE) {  // apply discount
    echo "Discount applied!!!\n";
} else {
    echo "no discount!\n";
}

$discount = discount_finder(6, $comparisons);
if ($discount == TRUE) {  // apply discount
    echo "Discount applied!!!\n";
} else {
    echo "no discount!\n";
}

$discount = discount_finder(13, $comparisons);
if ($discount == TRUE) {  // apply discount
    echo "Discount applied!!!\n";
} else {
    echo "no discount!\n";
}

?>