PHP中的语言构造和"内置"函数有什么区别?

Phi*_*ber 91 php function language-construct built-in

我知道include,isset,require,print,echo,和其他一些人都没有的功能,但语言结构.

其中一些语言结构需要括号,而其他语言结构则不需要.

require 'file.php';
isset($x);
Run Code Online (Sandbox Code Playgroud)

有些有返回值,有些则没有.

print 'foo'; //1
echo  'foo'; //no return value
Run Code Online (Sandbox Code Playgroud)

那么语言结构和内置函数之间的内部差异是什么?

Tim*_*Tim 129

(这比我预想的要长;请耐心等待.)

大多数语言都由称为"语法"的东西组成:语言由几个明确定义的关键字组成,您可以使用该语法构建完整的语言表达式.

例如,假设你有一个简单的四函数算术"语言",它只需要一位数的整数作为输入,完全忽略了操作的顺序(我告诉你它是一种简单的语言).该语言可以通过以下语法定义:

// The | means "or" and the := represents definition
$expression := $number | $expression $operator $expression
$number := 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
$operator := + | - | * | /
Run Code Online (Sandbox Code Playgroud)

根据这三个规则,您可以构建任意数量的单位输入算术表达式.然后,你可以写这句法,打破了任何有效的投入到它的组件类型(解析器$expression,$number$operator),并用结果的交易.例如,表达式3 + 4 * 5可以分解如下:

// Parentheses used for ease of explanation; they have no true syntactical meaning
$expression = 3 + 4 * 5
            = $expression $operator (4 * 5) // Expand into $exp $op $exp
            = $number $operator $expression // Rewrite: $exp -> $num
            = $number $operator $expression $operator $expression // Expand again
            = $number $operator $number $operator $number // Rewrite again
Run Code Online (Sandbox Code Playgroud)

现在,我们在已定义的语言中为原始表达式提供了完全解析的语法.一旦我们有了这个,我们可以通过编写一个解析器来查找所有组合的结果$number $operator $number,并在我们只剩下一个时吐出一个结果$number.

请注意,$expression在原始表达式的最终解析版本中没有留下任何构造.那是因为$expression在我们的语言中总是可以简化为其他事物的组合.

PHP大致相同:语言结构被认为是我们$number或的等价物$operator.它们不能被简化为其他语言结构 ; 相反,它们是构建语言的基本单位.函数和语言结构之间的关键区别在于:解析器直接处理语言结构.它将函数简化为语言结构.

语言构造可能需要或不需要括号的原因以及某些语法具有返回值的原因而其他语句不会完全取决于PHP解析器实现的特定技术细节.我不是那么精通解析器的工作方式,所以我不能专门解决这些问题,但想象一下这个以这个开头的语言:

$expression := ($expression) | ...
Run Code Online (Sandbox Code Playgroud)

实际上,这种语言可以自由地获取它找到的任何表达式并摆脱周围的括号.PHP(在这里我使用纯粹的猜测)可能会为其语言结构使用类似的东西:print("Hello")可能会print "Hello"在解析之前减少,反之亦然(语言定义可以添加括号以及去除它们).

这是为什么你不能重新定义像echo或者语言结构的根本原因print:它们被有效地硬编码到解析器中,而函数被映射到一组语言结构,并且解析器允许你在编译或运行时更改该映射替换您自己的一组语言结构或表达式.

在一天结束时,构造和表达式之间的内部差异是这样的:语言构造由解析器理解和处理.在语法提供的同时,内置函数在解析之前被映射并简化为一组语言结构.

更多信息:

编辑:通过阅读其他一些答案,人们可​​以提出好的观点.其中:

  • 内置语言比函数更快地调用.这是正确的,如果只是边际,因为PHP解释器在解析之前不需要将该函数映射到其语言内置的等价物.但是,在现代机器上,差异可以忽略不计.
  • 内置的语言绕过错误检查.这可能是也可能不是,这取决于每个内置的PHP内部实现.毫无疑问,通常情况下,函数会有更高级的错误检查和内置函数不具备的其他功能.
  • 语言结构不能用作函数回调.这是事实,因为构造不是函数.他们是独立的实体.当你对内置函数进行编码时,你不会编写一个带参数的函数 - 内置函数的语法由解析器直接处理,并被识别为内置函数而不是函数.(如果您考虑具有一流功能的语言,这可能更容易理解:实际上,您可以将函数作为对象传递.您不能使用内置函数来执行此操作.)

  • 很好的答案是开放式的,足以应用于许多语言,而不仅仅是PHP.谢谢! (2认同)

Pas*_*TIN 15

语言结构由语言本身提供(如"if","while",......等指令); 因此他们的名字.

这样做的一个结果是它们比预定义或用户定义的函数更快被调用(或者我已经多次听到/读过)

我不知道它是如何完成的,但他们可以做的一件事(因为直接集成到语言中)是"绕过"某种错误处理机制.例如,isset()可以与不存在的变量一起使用,而不会引起任何通知,警告或错误.

function test($param) {}
if (test($a)) {
    // Notice: Undefined variable: a
}

if (isset($b)) {
    // No notice
}
Run Code Online (Sandbox Code Playgroud)

*请注意,并非所有语言的结构都是如此.

函数和语言结构之间的另一个区别是,其中一些可以不带括号调用,就像关键字一样.

例如 :

echo 'test'; // language construct => OK

function my_function($param) {}
my_function 'test'; // function => Parse error: syntax error, unexpected T_CONSTANT_ENCAPSED_STRING
Run Code Online (Sandbox Code Playgroud)

在这里,所有语言结构都不是这样.

我想绝对没有办法"禁用"语言结构,因为它是语言本身的一部分.另一方面,许多"内置"PHP函数并不是真正内置的,因为它们是由扩展提供的,因此它们始终处于活动状态(但不是全部)

另一个区别是语言结构不能用作"函数指针"(我的意思是,回调,例如):

$a = array(10, 20);

function test($param) {echo $param . '<br />';}
array_map('test', $a);  // OK (function)

array_map('echo', $a);  // Warning: array_map() expects parameter 1 to be a valid callback, function 'echo' not found or invalid function name
Run Code Online (Sandbox Code Playgroud)

我现在脑子里还没有任何其他的想法...而且我对PHP的内部结构知之甚少...所以现在就是这样^^

如果你在这里没有得到多少答案,也许你可以问邮件列表内部(请参阅http://www.php.net/mailing-lists.php),其中有许多PHP核心开发人员; 他们可能会知道那些东西^^

(我真的对其他答案很感兴趣,顺便说一下^^)

作为参考:PHP中的关键字和语言结构列表