如何 return PHP 字符串的文字值使其作为代码运行?

How do I return literal values of a PHP string so it runs as code?

即使在这里我也不确定我是否使用了正确的术语,但我会尽力解释。我正在使用 PHP 的 array_filter 函数来过滤产品,它会回调到我在添加过滤器时创建的自定义函数。我可以很容易地完成这个硬编码,但我显然希望它是动态的:

长话短说,自定义过滤器函数 returns 到 array_filter() 函数如下:

return ($arr['colour']=='Red' || $arr['colour']=='White');

如果像上面那样进行硬编码,这会很好地工作,并按预期过滤数组以仅显示红色或白色的产品。但是,我需要它是动态的。

那么我如何构建一个值字符串,然后在 return 语句中使用它?

例如:

$var = "$arr['colour'] == 'Red' || $arr['colour'] == 'White'";
return ($var);

它不起作用。我试过使用 eval()(反正我不想用这个!),但还是不行。

我有一个循环,如下所示从数组构造字符串:

// $value=array of filters e.g colour=Black, colour=Red

$filterparts = explode("=", $value);

$filters[] = '$arr[\'' . $filterparts[0] . '\'] == \'' . $filterparts[1] . '\'';
// Creates array e.g $arr['colour'] = 'Red'

$imploded_filter = implode(" || ", $uniquefilters);
// Creates string, e.g. $arr['colour'] = 'Red' || $arr['colour'] = 'White'

所以如果我回显 $imploded_filter 我得到了我想要的提取字符串 return:

echo $imploded_filter;
// Outputs $arr['colour'] = 'Red' || $arr['colour'] = 'White'

但是如果我这样做

return($imploded_filter);

这显然不是将字符串评估为硬代码,那我该怎么办?我是否需要对字符串或以不同的方式 return 做一些事情,或者以完全不同的方式构建我需要 return 的代码?

$colors = ['Red', 'White'];
$products = array_filter($products, function ($product) use ($colors) {
    return in_array($product['color'], $colors);
});

几乎没有任何理由或需要"dynamically create PHP source code"。总有一种操作可以对任意数量的元素执行您想要的操作,而无需连接 || 运算符。这里 in_array 是一个非常好的函数,用于测试一个值与多个值的对比。您可以使用 use ($colors).

动态传递颜色数组

古代 PHP 版本最明智的解决方法是用 class:

来近似匿名回调
class InArrayFilterCallback {

    public $data = array();
    public $key;

    public __construct($data, $key) {
        $this->data = $data;
        $this->key = $key;
    }

    public callback($item) {
        return in_array($item[$this->key], $this->data);
    }

}

$products = array_filter($products, array(new InArrayFilterCallback($colors, 'color'), 'callback'));

当然,您也可以只使用一个简单的 foreach 循环...

可以动态指定数组键。不需要 eval():

$value = $array[$key];

您可以构建过滤器列表并在 array_filter() 回调中匹配每个过滤器:

$filters = array(
    array('colour', array('white', 'blue')), // Multiple accepted values (OR)
    array('material', 'Fine Bone China'), // Single accepted value
);

$filtered = array_filter($products, function ($item) use ($filters) {
    // Match all filters
    foreach ($filters as $filter) {
        // Detect multi-value filter
        $isArrayFilter = is_array($filter[1]);

        if (
            // Check if multi-value filter doesn't match
            $isArrayFilter && !in_array($item[$filter[0]], $filter[1])
            // Check if a single-value filter doesn't match
            || !$isArrayFilter && $item[$filter[0]] != $filter[1]
        ) {
            // Filter doesn't match - exclude the item
            return false;
        }
    }

    // All filters match - include the item
    return true;
});

使用in_array函数,像这样:

$filters = [
    'colour' => [
        'red',
        'blue',
    ]
];
array_filter($list, function ($item) use ($filters) {
    foreach ($filters as $index => $filter) {
        if (!in_array($item[$index], $filter)) {
            return false;
        }
    }
    return true;
});

创建一个字符串并对其求值从来都不是一个好主意。