我正在尝试使用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
值?
答案 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';
}
);