我很确定这个问题的答案是否定的,但是如果有一些PHP专家
是否有可能编写一种函数,使其可以传入无效的参数或不存在的变量,并且不使用'@' php不会出错
就像empty和isset一样。 您可以传入一个刚创建的变量,它不会出错。
1 2 3 4 5
| ex:
empty($someBogusVar); // no error
myHappyFunction($someBogusVar); // Php warning / notice |
通过引用传递变量时不会出现任何错误(PHP会静默创建一个新变量):
1 2 3
| function myHappyFunction(&$var)
{
} |
但是我建议您不要滥用它以隐藏编程错误。
总结一下,正确的答案是"否",您不应该这样做(请参见下面的警告)。
该线程中已经有很多人提到过一些变通办法,例如在条件中使用引用变量或isset()或empty()并禁止PHP配置中的通知。除了明显的解决方法外,您还不需要使用@。
总结一下与Gerry进行的有趣的评论讨论:如果您在函数内检查变量的值并正确处理未定义或空的情况,则通过引用传递变量确实有效。只是不要使用引用传递作为关闭PHP的一种方式(这是我的原始文章不应该指向的地方)。
您可以这样使用func_get_args来做到这一点:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| error_reporting(E_ALL);
ini_set('display_errors', 1);
function defaultValue() {
$args = func_get_args();
foreach($args as $arg) {
if (!is_array($arg)) {
$arg = array($arg);
}
foreach($arg as $a) {
if(!empty($a)) {
return $a;
}
}
}
return false;
}
$var = 'bob';
echo defaultValue(compact('var'), 'alpha') ."
"; //returns 'bob'
echo defaultValue(compact('var2'), 'alpha') ."
"; //returns 'alpha'
echo defaultValue('alpha') ."
"; //return
echo defaultValue() ."
"; |
此函数进一步走了一步,将为您提供任意数量的args的第一个非空值(您可以始终强制它最多使用两个args,但这对我来说似乎更有用)。
编辑:原始版本没有使用compact来尝试使args数组,并且STILL给出了错误。错误报告增加了一个缺口,这个紧凑的新版本虽然没有那么整洁,但是仍然可以做同样的事情,并且允许您为不存在的var提供默认值。
在某些情况下,检查变得繁琐和不必要。
因此,我编写了这个小魔术函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| /**
* Shortcut for getting a value from a possibly unset variable.
* Normal:
* if (isset($_GET['foo']) && $_GET['foo'] == 'bar') {
* Short:
* if (value($_GET['foo']) == 'bar') {
*
* @param mixed $variable
* @return mixed Returns null if not set
*/
function value(&$variable) {
if (isset($variable)) {
return $variable;
}
} |
它不需要对myHappyFunction()进行任何更改。
你必须改变
1
| myHappyFunction($someBogusVar); |
至
1
| myHappyFunction(value($someBogusVar)); |
明确说明您的意图。这是我书中的最佳做法。
is it possible to write a function in a way where invalid arguments or non existent variables can be passed in and php will not error without the use of '@'
是的你可以!
porneL是正确的[编辑:我没有足够的积分可以链接到他的答案或投票,但是它在此页上]
当他警告"但我建议您不要滥用它以隐藏编程错误"时,他也是正确的。但是,出于同样的原因,也应避免通过错误控制运算符(@)进行错误抑制。
我是Stack Overflow的新手,但我希望不正确的答案在页面上排名最高而正确的答案未获得投票的情况并不常见。 :(
不,因为这实际上与该功能无关。该错误来自尝试取消引用不存在的数组键。您可以更改PHP设置的警告级别以消除这些错误,但是最好不要这样做。
话虽如此,你可以做类似的事情
1 2 3 4 5 6 7
| function safeLookup($array, $key)
{
if (isset($array, $key))
return $array[$key];
return 0;
} |
并使用它代替数组键查找
1
| defaultValue(safeLookup($foo,"bar"),"baz); |
现在我要洗个澡:)
只需一行,您就可以完成:myHappyFunction($someBogusVar="");
我希望这是您要寻找的。如果您阅读了php文档,则在默认参数值下,可以看到将默认值分配给函数的参数可以帮助您防止在使用函数时出现错误消息。
在此示例中,您可以看到使用默认参数的区别及其优点:
PHP代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <?php
function test1($argument)
{
echo $argument;
echo"
";
}
function test2($argument="")
{
echo $argument;
echo"
";
}
test1();
test1("Hello");
test1($argument);
$argument ="Hello world";
test1($argument);
test2();
test2("Hello");
test2($argument);
$argument ="Hello world";
test2($argument);
?> |
test1()行的输出:
Warning: Missing argument 1 for test1() .
Hello.
.
Hello world.
test2()行的输出:
.
Hello.
Hello world.
也可以将其与isset()和其他功能结合使用以完成所需的操作。
如果仅向参数添加默认值,则可以在调用函数时跳过它。例如:
1 2 3 4 5 6 7 8
| function empty($paramName =""){
if(isset($paramName){
//Code here
}
else if(empty($paramName)){
//Code here
}
} |
原始问题的答案是"否",但没有人提到任何选择。
当使用@符号时,所有PHP都在覆盖error_reporting级别并将其临时设置为零。您可以使用" ini_restore('error_reporting');"将其设置回使用@之前的状态。
在我想编写一个便利函数来检查并查看是否设置了变量并具有其他一些属性的情况下,这对我很有用,否则,返回默认值。但是,通过发送未设置的变量会引起PHP通知,因此我使用了@来禁止这样做,然后将error_reporting设置回函数内部的原始值。
就像是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| $var = @foo($bar);
function foo($test_var)
{
ini_restore('error_reporting');
if(is_set($test_var) && strlen($test_var))
{
return $test_var;
}
else
{
return -1;
}
} |
因此,在上述情况下,如果未设置$bar,则在使用不存在的变量调用foo()时不会出现错误。但是,我会在错误键入is_set而不是isset的函数中收到错误消息。
如果不是实际问题,这可能是一个有用的选项,可以涵盖原始问题的实质内容。
肖恩,您可以这样做:
1
| $result = ($func_result = doLargeIntenseFunction()) ? $func_result : 'no result'; |
编辑:
I'm sure there could be a great
discussion on ternary operators vrs
function calls. But the point of this
question was to see if we can create a
function that won't throw an error if
a non existent value is passed in
without using the '@'
我告诉过您,请使用isset()进行检查。三元条件的第一部分不检查null或不为null,而是检查true或false。如果尝试在PHP中的空值上检查true或false,则会收到这些警告。 isset()检查变量或表达式是否返回空值,并返回一个布尔值,可以由三进制的第一部分对其进行评估,而不会出现任何错误。
@Sean Brian已经回答了
1
| return isset($input) ? $input : $default; |
我敢肯定,关于三元运算符vrs函数调用的讨论可能会很多。但是这个问题的重点是看是否可以创建一个函数,如果不使用'@'传递不存在的值,该函数将不会引发错误。
@Brian: I use a trinary operation to do the check for me:
1
| return $value ? $value : $default; |
这将返回$ value或$ default。取决于$ value的值。如果为0,false,空或类似的内容,则将返回$ default中的值。
我更想挑战模拟empty()和isset()之类的函数
进一步深入到抽象树,您将其用于什么?
您可以根据需要在每个类中初始化这些值,也可以创建一个包含所有默认值和属性的特定类,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class Configuration {
private var $configValues = array( 'cool' => 'Defaultcoolval' ,
'uncool' => 'Defuncoolval' );
public setCool($val) {
$this->configValues['cool'] = $val;
}
public getCool() {
return $this->configValues['cool'];
}
} |
这样的想法是,当在代码中到处使用defaultValue函数时,每当您必须更改值,查找放置了DefaultValue调用的所有位置时,它将成为维护的噩梦。而且可能还会导致您重复自己,违反了DRY。
而这是一个用于存储所有这些默认值的地方。您可能会想避免创建那些setter和getter,但是如果需要进行一些输出修改或输入验证,它们也将有助于维护。