为什么定义一个函数被视为不止一条语句?

3

我在 PHP 中看到了一个奇怪的行为。看下面这个例子:

<?php
if (true)
    function my_function(){
        echo "here";
    }

my_function();
?>

运行此命令会出现错误:

解析错误:第 4 行出现意外的 'my_function'(T_STRING),期望 '('

我发现修复此错误的方法是添加括号:

<?php
if (true) {
    function my_function(){
        echo "here";
    }
}
my_function();
?>

这段代码将会正确执行。

你能解释一下吗?为什么定义一个函数算作多于一个语句?


2
虽然你可以省略开头的括号,但这并不是一个好习惯。如果条件块超过一行,省略括号会导致奇怪的解析错误,这也是我不喜欢省略它的原因。 - treyBake
函数手册中指出:“函数在被引用之前不需要被定义,除非函数是有条件地定义,就像下面两个示例所示。当函数以有条件的方式定义时,如下面两个示例所示。它的定义必须在调用之前进行处理。” - Funk Forty Niner
3
除了这个函数被有条件地定义之后才被调用之外,逻辑上应该没有区别:if(true) function my_function() { echo "here"; }if(true) { function my_function() { echo "here"; } } ... 但第一个会抛出语法错误,第二个可以正常工作。 - CD001
2
他们应该(始终)使用适当的括号,然后@CD001,这可能是错误的根源。 - Funk Forty Niner
1
@FunkFortyNiner - 我不是在争论那个;) ... 甚至条件函数的想法也不对我来说...但是逻辑上我认为OP有一点道理。if($foo) echo "bar"没问题,但是if($foo) function bar() {}就不行...我不确定为什么。虽然我以前从未尝试过这样做,但这种行为似乎...不直观。 - CD001
显示剩余2条评论
1个回答

1

函数定义不是语句。

你问道:

为什么定义函数算作多于一条语句?

实际上并不算。定义函数不是语句。

来自 PHP手册

语句可以是赋值、函数调用、循环、条件语句,甚至是什么也不做的语句(空语句)。语句通常以分号结尾。此外,通过使用花括号将一组语句封装起来,语句也可以被组合成一个语句组。语句组本身也是一条语句。

if 语句必须跟随另一条语句!让我们简化你的问题,并看一下上述定义中的一些例子:

if(1)
    {} // A statement-group is a statement by itself as well.
if(1)
    ; // an empty statement
if(1)
    $a=1; // an assignment
if(1)
    print(1); // a function call
if(1)
    while(0){} // a loop
if(1)
    if(0); // a conditional statement

根据官方PHP定义,函数或类的定义不是语句。非语句不能在需要语句的上下文中使用。
何时函数定义是语句?
PHP 5.3引入了匿名函数(Lambda函数和闭包)的概念。匿名函数定义是一种语句。
匿名函数的语法与普通函数定义几乎相同,但您应该不提供名称。换句话说,关键字"function"后面必须跟随"()",它们之间只允许空格。它还必须以分号结尾。
// This is valid:
if(1)
    function (){};
//This is invalid:
if(1)
    function a(){}
//           ^
// syntax error, unexpected 'a' (T_STRING), expecting '('

这就是为什么错误信息告诉你函数名称不符合预期。PHP期望一个语句,当遇到 "function" 关键字时,它期望你正在定义一个匿名函数。匿名函数没有名称,因此名称部分不符合预期。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接