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