请考虑以下代码。它具有ensure_default()
帮助程序,该帮助程序将变量设置为false时将默认值分配给变量:
function resource_intensive_lookup() {
echo 'Running '.__FUNCTION__.'<br>';
return 'default_value';
}
function ensure_default(&$var, $default_value)
{
if (! $var) {
$var = $default_value;
}
}
$var = 'some_value';
ensure_default($var, resource_intensive_lookup());
print_r($var);
问题在于,即使$var
设置为非假值,resoursive_intensive_lookup()
仍将被调用。我可以通过仅传递函数名称作为参数并在call_user_func()
中使用ensure_default()
来防止这种情况,但是如果代码库具有更多类似于ensure_default()
的函数,则这种方法的伸缩性将不会很好
我也尝试过使用闭包来防止不必要地调用resource_intensive_lookup()
,但是当最初$ var开始时,不幸地将$var
设置为Closure Object ( )
而不是default_value
设置为false:
$closure = function () {
return resource_intensive_lookup();
};
function resource_intensive_lookup() {
echo 'Running '.__FUNCTION__.'<br>';
return 'default_value';
}
function ensure_default(&$var, $default_value)
{
if (! $var) {
$var = $default_value;
}
}
$var = false;
ensure_default($var, $closure);
print_r($var);
答案 0 :(得分:1)
您问题中的最后一个例子几乎不错。您需要更改:
$var = $default_value;
收件人:
$var = $default_value();
编辑:
如果您不想更改ensure_default
,我能想到的唯一解决方案是创建自己的代理,如果ensure_default
返回它,它将调用可调用对象并对其进行调用代理而不是原始的ensure_default
:
function ensure_default_with_callback(&$var, $default_value) {
ensure_default($var, $default_value);
if (is_callable($var)) {
$var = $var();
}
}
ensure_default_with_callback($var, $closure);
// you can also call it without closure
ensure_default_with_callback($var, "not a closure");
答案 1 :(得分:0)
如果您可以将初始化作为匿名函数传递,则只有在需要时才可以调用该函数...
function ensure_default(&$var, $default_value)
{
if (! $var) {
$var = $default_value();
}
}
$var = 'some_value'; // Values used for testing
$var = null;
ensure_default($var, function () {
echo 'Running '.__FUNCTION__.'<br>';
return 'default_value';
});
print_r($var);
编辑:
如果您希望ensure_default()
能够处理函数或文字值,则可以检查$default_value
是否可调用...
function ensure_default(&$var, $default_value)
{
if (! $var) {
$var = (is_callable($default_value))?$default_value():$default_value;
}
}
哪个允许...
$var1 = 'some_value'; // Values used for testing
$var1 = null;
ensure_default($var1, 'default_value1');
print_r($var);
将默认值设置为字符串(或实际上大多数其他值)。
答案 2 :(得分:0)
为什么不$var = 'some_value' || resource_intensive_lookup()
?我想'some_value'
在现实世界中将是一个变量,但是我认为代码片段抓住了这个想法。