函数指定非空的参数

Wes*_*nal 5 php parameters null function variable-assignment

这是我上一个问题的后续问题.

运行没有参数的函数但需要函数外部的变量 - PHP

我收到了这个答案

function foo($arg1 = null, $arg2 = null) {
    // if they are not set retrieve from a session
    $arg1 = ($arg1 !== null) ? $arg1 : $_SESSION['arg1'];
   // rinse repeat.
}
Run Code Online (Sandbox Code Playgroud)

所以我想,也许我可以通过阻止在每个函数上调用相同的变量来减少代码行.

我想出了这个.

function foo($arg1 = $_SESSION['user_id'], $arg2 = $_SESSION['campaign_id']) {
     //do something
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,我收到了这个错误.

Parse error: syntax error, unexpected T_VARIABLE
Run Code Online (Sandbox Code Playgroud)

它有结果导致这个问题吗?我只是用一个带有值的变量替换了null.

有没有办法分配一个函数,该函数的参数已经有一个值而不是赋值为null?

PS

我正在尝试使用输出数据echo $campaign->getName(),因此在调用函数时没有提供参数.

所以我试图调用这样的函数

function foo($arg1 = $_SESSION['user_id'], $arg2 = $_SESSION['campaign_id']) {
     //do something
}
Run Code Online (Sandbox Code Playgroud)

如果没有任何方法可以一次又一次地调用相同的变量.

任何帮助,将不胜感激.:)

bwo*_*ebi 8

TL;博士

不要尝试(它甚至不会像你看到的那样工作),使用适当的DI(依赖注入)并将外部(全局)变量作为参数传递:

// functions should be deterministic — require the arguments in favour of using dynamic defaults
function foo($arg1 /* require it */, $arg2 = 1 /* static scalars as default is no problem */) {
    // your code
}
foo($_SESSION["user_id"]); // always pass dynamic arguments, don't fetch them in the function
Run Code Online (Sandbox Code Playgroud)

介绍

不能使用其他任何默认值作为所谓的静态标量.这些是文字(字符串,整数等),常量和(自PHP 5.6起)对这些文字/常量的操作.

所以...

两年多前我有同样的好主意,并提交了一份错误报告... https://bugs.php.net/bug.php?id=60544

今天我觉得这不是一个好主意.语言默认值应该是静态的.我怀疑那些设计PHP的人没有他们的理由.

但还有一种方法......

你怎么做到这一点(不推荐)

这里唯一的解决方法是使用常量.

function foo($arg = ARG) {
    var_dump($arg);
}
Run Code Online (Sandbox Code Playgroud)

在您确定该值不再更改的那一刻,在第一次调用函数之前定义常量:

define("ARG", $_SESSION["user_id"]);
Run Code Online (Sandbox Code Playgroud)

然后你可以稍后通过它来调用它foo();.

这可能是由于这里对常量的惰性评估.

这种方法的缺点是你必须定义一次常量,然后它将在其余的脚本运行时保持不变.

但我仍强烈不推荐它.它是hackish并且有很大的缺点.

你怎么可以做的更好

您已经向我们展示了如何做到这一点:

$arg1 = ($arg1 !== null) ? $arg1 : $_SESSION['arg1'];
Run Code Online (Sandbox Code Playgroud)

这绝对是正确的方法.如果你真的想这样做.

但你仍然不应该这样做.您正在从函数访问全局范围(超全局).

应该怎么做

语法设计者没有实现这种可能性的原因之一就是为什么我们不应该试图通过函数中的常量或全局范围访问来避免这种情况.

你真的应该正确使用依赖注入并通过参数将外部(全局)值传递给函数.(参见tl; dr部分中的示例)

您提出的这种类型的代码很容易导致难以调试的代码,因为人们可能不会期望真正的函数访问全局状态.

这就是为什么函数应该具有给定输入的确定性输出(除非它们被明确地认为是非确定性的,例如读取文件的函数),这极大地提高了可测试性和可移植性.


Mad*_*iha 6

你不能.

您只能将文字指定给函数默认值,即在运行时无法更改的常量值.这意味着,"actual strings",数字(42),硬编码阵列([1, 2, 3]), NULL.而不是$variables,function() {}或者在运行时可以更改的任何其他内容.

你也不应该.

如果你的功能取决于用户ID和活动ID,你应该将它们传递给你的功能,而不是依赖它们在SESSION,因为你无法知道它们是否真的在那里!.

不要依赖全局变量.


为什么不将参数传递给函数?它需要它们,不是吗?您是否希望以下功能在没有参数的情况下工作?

add($x, $y)
Run Code Online (Sandbox Code Playgroud)

仅仅因为这些参数来自SESSION,数据库或世界以外的其他参数?

不.该功能需要两个参数,因此,它应该要求给出两个参数.