PHP - 将if语句编码放在变量中

时间:2014-04-04 12:16:56

标签: php xml if-statement

我正在尝试使用if语句根据用户输入动态编码自己。所以if语句代码被插入到变量($if_statement_variable)中,如下所示:

$if_statement_variable = "if (";  

$price = trim($_GET["Price"]);
if (!empty($price)) {
$if_statement_variable .= " $Product->price < $price ";
}

$product_name = trim($_GET["Product_name"]);
if (!empty($product_name)) {
$if_statement_variable .= " && $Product->$product_name == 'product_name_string' ";
}

// plus many more if GET requests

$if_statement_variable .= ") ";

然后,将根据提交的用户值和$if_statement_variable显示XML文件的结果。

$XMLproducts = simplexml_load_file("products.xml");

foreach($XMLproducts->product as $Product) {

echo $if_statement_variable; // Here is where the problem is

{  // opening bracket for $variable_if_statement
echo $Product->$product_name;  // products displayed based on if statement code in    $if_statement_variable
}  //closing bracket for $variable_if_statement
}

上面的echo $if_statement_variable从此变量字符串中正确显示$price,但不显示$Product->price。假设$price的值为1000,则输出为if ( == 1000 )。如何让$Product->price将自己正确插入$if_statement_variable,以便显示XML文件中的$Product->price值?

2 个答案:

答案 0 :(得分:1)

如果您尝试动态生成布尔值,基于某些复杂的逻辑,只需将true / false值赋给变量(例如$booleanValue),然后执行if($booleanValue){} < / p>

类似的东西:

$price = trim($_GET['price']);
$product_name = trim($_GET['Product_name']);
if(!empty($price)){
  $booleanValue = ($Product->price < $price);
}
if(!empty($productName)){
  $booleanValue = ($booleanValue && $Product->$product_name == 'product_name_string')
}
if($booleanValue){
  echo $Product->$product_name;
}

换句话说,创建一个变量来保存实际的布尔值,而不是一个字符串来保存一个将计算为布尔值的表达式。

答案 1 :(得分:1)

不要将PHP源代码构建为字符串。在这种情况下,callable是一个更好的解决方案。可调用是变量内的函数。在PHP中,这可能是一个函数名,带有对象和方法名的数组,匿名函数或实现调用的对象。

以下是匿名函数的示例:

function getCondition($parameters) {
  $conditions = [];
  if (isset($parameters['Price']) && trim($parameters['Price']) != '') {
    $price = trim($parameters['price']);
    $conditions[] = function($product) use ($price) {
      return $product->price < $price;
    }
  } 
  if (isset($parameters['Product_name']) && trim($parameters['Product_name']) != '') {
    $productName = trim($parameters['Product_name']);
    $conditions[] = function($product) use ($productName) {
      return $product->product_name == $productName;
    }
  } 
  return function($product) use ($conditions) {
    foreach ($conditions as $condition) {
      if (!$condition($product)) {
        return FALSE;
      }
    }
    return TRUE;
  }
}


$condition = getConditon($_GET);

if ($condition($product)) { 
  ...
}

重要的是,每个函数都可以以相同的方式调用。因此,如果你调用条件函数,你不需要知道它是什么条件。在上面的示例中,您可以想象如果添加其他条件,getCondition()函数可以非常快速地复杂化。

如果将条件封装到类中,则使用变得更具可读性:

$condition = new \YourCompany\Product\Conditions\Group(
  new \YourCompany\Product\Conditions\PriceMaximum($_GET, 'Price'),
  new \YourCompany\Product\Conditions\Name($_GET, 'Product_name')
);

if ($condition($product)) { 
  ...
}

这样您就可以将实际条件逻辑与使用中的逻辑分开。所有类的源代码都是匿名函数变体。但是你可以将每个类放在它自己的文件中,并以你需要的任何组合使用它们。

这些类需要实现__invoke()。

class Group {

  private $_conditions = array();

  public function __construct() {
    $this->_conditions = func_get_args();
  }

  public function __invoke($product) {
    foreach ($this->_conditions as $condition) {
      if (!$condition($product)) {
        return FALSE;
      }
    }
    return TRUE;
  }
}

class Name {

  private $_productName = NULL;

  public function __construct($parameters, $name) {
    if (isset($parameters[$name]) && trim($parameters[$name]) > 0) {
      $this->_productName = trim($parameters[$name]);
    }
  }

  public function __invoke($product) {
    return (
      NULL === $this->_productName ||
      $product->product_name == $this->_productName 
    );
  }
}

class PriceMaximum {

  private $_maximum = NULL;

  public function __construct($parameters, $name) {
    if (isset($parameters[$name]) && trim($parameters[$name]) > 0) {
      $this->_maximum = trim($parameters[$name]);
    }
  }

  public function __invoke($product) {
    return (
      NULL === $this->_maximum ||
      $product->price < $this->_maximum
    );
  }
}

这个概念甚至可以与匿名函数一起使用:

$condition = new \YourCompany\Product\Conditions\Group(
  new \YourCompany\Product\Conditions\PriceMaximum($_GET, 'Price'),
  new \YourCompany\Product\Conditions\Name($_GET, 'Product_name'),
  function ($product) {
    return $product->category == 'food';
  }
);