PHP文档中的示例:
http://php.net/manual/en/function.openssl-public-encrypt.php
openssl_public_encrypt (
string $data , string &$crypted , mixed $key [, int $padding =
OPENSSL_PKCS1_PADDING ]
)
在这种情况下,它期望$crypted作为传递的引用。该函数在没有预先设置$crypted的情况下工作。
在很多例子中,我看到$crypted在调用函数之前被初始化。
var $crypted = '';
这真的需要吗(或者技术上更正确),或者即使变量是"通过引用"变量,也不设置变量可以吗?
与其说是一个答案,不如说是一条评论-但对于评论框来说太长了。还有一个有趣的问题,让我不禁要问"为什么"。
直接回答:
- 不声明变量不会在任何一个版本中引起"通知",因此从技术上讲,这是不需要的
- 因此,申报是一件优惠的事情。像亚历克斯一样,我更喜欢声明可读性和清晰度。(我也更喜欢避免像
extract
这样在任何地方创建变量的函数。)但我相信其他人会不同意
但这就引出了一个问题,为什么它会这样工作?我很想知道。
首先要注意的是,从PHP 5到PHP 7,变量和通过引用传递的变量发生了很大变化。这里有一个有趣的阅读:https://nikic.github.io/2015/05/05/Internal-value-representation-in-PHP-7-part-1.html这就解释了差异。
但在这两个PHPs中,变量都存储在zval空间中,并带有一个引用次数的引用计数器。(上面的文档是我找到的解释它的最好例子,但手册中还有更多)
当您扩展PHP并添加新函数时,您可以使用zend_parse_parameters
从Zend API获取变量。这意味着传递给函数的变量也存储在zval容器中,并在API和扩展之间传递。(进一步阅读-这与PHP5有关,但与PHP7相同)。
我的理解(我很高兴被纠正)在四个代码示例中得到了解释:
1)
function increment($i) {
$i++;
}
increment(3);
变量3
没有声明(显然),但它需要在zval容器中才能传递给API。这表明调用函数能够在zval容器中生成变量。(由于它不是一个真正的变量,我认为它"不可变",但这只是猜测。)
2)
function increment($i) {
$i++;
}
increment($y);
由于未首先声明$y
,因此会出现此错误。Notice: Undefined variable: y in test.php
。因此,在这里它无法生成$y
并放入本地范围。
3)
function increment($i) {
$i++;
}
$y = 0;
increment($y);
变量被声明并放入zval容器中。在调用函数时,refcount将增加,以便将其传递给API。工作符合预期。
4)
function increment(&$i) {
$i++;
}
increment(3);
这会使Fatal error: Only variables can be passed by reference in test.php
出错。这告诉我们变量3
被zend_parse_parameters
拒绝,因为它知道它是不可变的,或者调用函数知道函数通过引用期望一个变量。
5)
function increment(&$i) {
$i++;
}
$y = 0;
increment($y);
变量$y
被放入第一行当前作用域中的zval容器中,并生成指向$y
的引用指针(增加refcount两次)。
6)
function increment(&$i) {
$i++;
}
increment($y);
这就是梨形IMO的走向:虽然变量没有声明,但$y == 1
。这意味着函数必须创建变量并放入当前作用域中的zval容器中,并生成指向$y
的引用指针(增加refcount)。
要做到这一点,它必须知道函数通过引用期望一个值——否则,为什么行为与2不同?
这些都不能回答为什么它不同。仅仅因为它可以创建一个变量(如示例1所示),为什么它在示例2中不创建,而在示例6中创建?
尽管会创建变量,但我更喜欢显式设置它,原因有很多:
- 函数中可能使用变量从中获取数据
- 这个变量可能没有在函数中设置,所以之后我不需要麻烦
isset
- 变量可能已经在代码的其他地方定义了,因此如果函数不更改变量,就有传递垃圾或接收垃圾的风险
- 我忘了提到的肯定很少,所以让我们把它命名为直觉
不确定它们是否特别适用于openssl_public_encrypt
,但由于您习惯于在函数调用之前设置变量,因此更改这种行为需要付出更多的努力和关注。