我很确定这个问题的答案是否定的,但是如果有一些PHP大师
是否有可能以一种方式编写函数,其中可以传入无效参数或不存在的变量,并且如果不使用'@'
很像空和isset。您可以传入刚刚编写的变量,也不会出错。
ex:
empty($someBogusVar); // no error
myHappyFunction($someBogusVar); // Php warning / notice
答案 0 :(得分:9)
当通过引用传递变量时,您不会收到任何错误(PHP将以静默方式创建新变量):
function myHappyFunction(&$var)
{
}
但我建议不要滥用它来隐藏编程错误。
答案 1 :(得分:7)
总结一下,正确的答案是不,你不应该(见下面的警告)。
此线程中已有许多人提到过变通方法,例如在条件中使用引用变量或isset()或empty()以及在PHP配置中抑制通知。除了明显的解决方法之外,使用@,你不需要它。
总结与Gerry的有趣评论讨论:如果检查函数内部变量的值并正确处理undefined或null情况,则通过引用传递变量确实有效。只是不要使用引用传递作为关闭PHP的方法(这是我原来不应该指向的地方)。
答案 2 :(得分:3)
你可以使用func_get_args这样做:
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') . "\n"; //returns 'bob'
echo defaultValue(compact('var2'), 'alpha') . "\n"; //returns 'alpha'
echo defaultValue('alpha') . "\n"; //return
echo defaultValue() . "\n";
这个函数更进了一步,它将为你提供任意数量的args的第一个非空值(你可以总是强迫它只占用两个args但这看起来对我来说更有用)。
编辑:原始版本没有使用compact来尝试创建一个args数组,而STILL则给出了错误。错误报告提升了一个档次,这个带有compact的新版本有点不整齐,但仍然做同样的事情,并允许您为不存在的变量提供默认值。答案 3 :(得分:2)
有些情况下,检查变得繁琐且无关紧要 因此,我写了这个小小的神奇功能:
/**
* 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()进行任何更改。
你必须改变
myHappyFunction($someBogusVar);
到
myHappyFunction(value($someBogusVar));
明确说明您的意图。这使我的书中的良好做法。
答案 4 :(得分:1)
不,因为这与功能无关;该错误来自于尝试取消引用不存在的数组键。您可以更改PHP设置的警告级别来抑制这些错误,但最好不要这样做。
话虽如此,你可以做类似
的事情function safeLookup($array, $key)
{
if (isset($array, $key))
return $array[$key];
return 0;
}
并使用它代替数组键查找
defaultValue(safeLookup($foo, "bar"), "baz);
现在我需要洗个澡。)
答案 5 :(得分:1)
是否有可能以一种方式编写一个函数,其中可以传入无效参数或不存在的变量,并且如果不使用'@',php将不会出错
是的,你可以!
porneL是正确的[编辑:我没有足够的分数链接到他的答案或投票,但它在这个页面上]
当他提醒时,他也是正确的“但我建议不要滥用这个来隐藏编程错误。”但是,出于同样的原因,也应避免通过错误控制操作符(@)进行错误抑制。
我是Stack Overflow的新手,但我希望不正确的答案在页面上排名最高而正确的答案没有得票。 :(
答案 6 :(得分:0)
@Brian:我使用三元操作为我做检查:
return $value ? $value : $default;
返回$ value OR $ default。取决于$ value的值。如果为0,则为false,为空或类似于$ default中的值将返回。
我更愿意接受挑战来模拟像empty()和isset()
这样的函数答案 7 :(得分:0)
我确信可以对三元运算符vrs函数调用进行很好的讨论。但问题的关键在于,如果在不使用'@'的情况下传入不存在的值,我们是否可以创建一个不会抛出错误的函数
答案 8 :(得分:0)
@Sean已经由Brian回答了
return isset($input) ? $input : $default;
答案 9 :(得分:0)
$result = ($func_result = doLargeIntenseFunction()) ? $func_result : 'no result';
编辑:
我相信可能会很棒 关于三元运算符的讨论 函数调用。但重点是这一点 问题是看看我们是否可以创建一个 如果,则不会抛出错误的函数 传入不存在的值 不使用'@'
我告诉过你,用isset()
检查一下。三元条件的第一部分不检查null或不为null,它检查true
或false
。如果您尝试在PHP中检查空值的true
或false
,则会收到这些警告。 isset()
检查变量或表达式是否返回空值,并返回一个布尔值,可以由三元组的第一部分进行评估而不会出现任何错误。
答案 10 :(得分:0)
虽然原始问题的答案是“不”,但没有人提到过选项。
当您使用@符号时,所有PHP正在执行的操作将覆盖error_reporting
级别并暂时将其设置为零。您可以使用“ini_restore('error_reporting');
”将其设置回使用@之前的任何内容。
这对我来说很有用,我想编写一个方便函数来检查并查看变量是否已设置,并且还有一些其他属性,否则返回默认值。但是,通过引发PHP通知发送一个未设置的变量,所以我使用@来抑制它,但然后将error_reporting
设置回函数内的原始值。
类似的东西:
$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
的函数中收到错误。
这可能是一个有用的选项,涵盖了原始问题的精神要求,如果不是实际的话。
答案 11 :(得分:0)
如果只是为参数添加默认值,则可以在调用函数时跳过该参数。例如:
function empty($paramName = ""){
if(isset($paramName){
//Code here
}
else if(empty($paramName)){
//Code here
}
}
答案 12 :(得分:0)
只需一行,您就可以完成它:myHappyFunction($someBogusVar="");
我希望这就是你要找的东西。如果您阅读php文档,在default argument values下,您可以看到为函数的参数指定默认值可以帮助您在使用函数时防止出现错误消息。
在这个例子中,您可以看到使用默认参数的区别及其优点:
PHP代码:
<?php
function test1($argument)
{
echo $argument;
echo "\n";
}
function test2($argument="")
{
echo $argument;
echo "\n";
}
test1();
test1("Hello");
test1($argument);
$argument = "Hello world";
test1($argument);
test2();
test2("Hello");
test2($argument);
$argument = "Hello world";
test2($argument);
?>
test1()
行的输出:
警告:缺少test1()的参数1 你好。
。
你好世界。
test2()
行的输出:
。
你好。
你好世界。
这也可以与isset()
和其他功能结合使用,以达到你想要的效果。
答案 13 :(得分:-1)
进一步提升抽象树,你用它做什么?
您可以根据需要在每个类中初始化这些值,也可以创建包含所有默认值和属性的特定类,例如:
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,但是它们也有助于维护,以防它对输出的修改或输入的验证有用。