语言结构和“内置”结构之间的区别是什么?函数在PHP中? [英] What is the difference between a language construct and a "built-in" function in PHP?

查看:166
本文介绍了语言结构和“内置”结构之间的区别是什么?函数在PHP中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道包含 isset require print echo ,还有一些不是函数,而是语言结构。

这些语言结构中的一些需要括号,其他语言不需要。

 需要'file.php'; 
isset($ x);

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

  print'foo'; // 1 
echo'foo'; //没有返回值

那么,一种语言的内部区别是什么?构造和内置函数?

解决方案

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



大多数语言都是由一些称为语法的东西组成的:语言由几个定义明确的关键字组成,您可以用该语言构建的完整表达式范围是例如,假设你有一个简单的四函数算术语言,它只将单位数的整数作为输入,并完全忽略顺序(我告诉你这是一种简单的语言)。该语言可以由语法定义:

  // The |意思是或,而:=代表定义
$表达式:= $ number | $表达式$ operator $表达式
$ number:= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
$ operator:= + | - | * | /

从这三条规则中,您可以构建任意数量的单数字输入算术表达式。然后,您可以为此语法编写一个解析器,将任何有效的输入分解为其组件类型( $ expression $ number $ operator )并处理结果。例如,表达式 3 + 4 * 5 可以细分为如下形式:

  //圆括号用于解释的方便;他们没有真正的语法意义
$ expression = 3 + 4 * 5
= $ expression $ operator(4 * 5)//展开到$ exp $ op $ exp
= $ number $运算符$表达式//重写:$ exp - > $ num
= $ number $ operator $ expression $ operator $ expression //再次展开
= $ number $ operator $ number $ operator $ number // Rewrite再次

现在我们有了一个完全解析的语法,用我们定义的语言来表示原始表达式。一旦我们有了这个,我们可以通过编写一个解析器来查找 $ number $ operator $ number 的所有组合的结果,并且只在我们有一个 $数字左边。



请注意,没有 $表达式 code>结构保留在原始表达式的最终解析版本中。这是因为 $ expression 总是可以归结为我们的语言中的其他内容。



PHP很多相同:语言结构被认为与我们的 $ number $运算符等价。它们不能被缩减为其他语言结构;相反,它们是构建语言的基本单位。函数和语言结构之间的关键区别在于:解析器直接处理语言结构。它将函数简化为语言结构。



语言结构可能需要或不需要圆括号的原因以及某些返回值的原因,而其他原因则完全取决于具体PHP解析器实现的技术细节。我对解析器的工作方式并不太熟悉,所以我无法专门解决这些问题,但想象一下以此开始的语言:

  $表达式:=($表达式)| ...  

实际上,这种语言可以自由地将它找到的任何表达式去除并排除周围的圆括号。 PHP(在这里我使用纯猜测)可能会使用类似的语言构造: print(Hello)可能会减少到在解析之前打印Hello,反之亦然(语言定义可以添加圆括号以及去除它们)。



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



<在一天结束时,结构和表达式之间的内部差异是这样的:语言结构可以被解析器理解和处理。内置函数虽然由语言提供,但在解析之前会映射并简化为一组语言结构。



更多信息:





编辑:阅读通过其他一些答案,人们提出了很好的观点。其中:


  • 语言内置函数比函数更快。这是真的,如果只是勉强,因为在解析之前,PHP解释器不需要将该函数映射到它的语言内置等价物。然而,在现代机器上,差异是微不足道的。

  • 语言内置绕过错误检查。这可能会也可能不会是真实的,这取决于每个内置的PHP内部实现。确实,更多的时候,函数会有更高级的错误检查和其他内建的功能。

  • 语言结构不能用作函数回调函数。这是真的,因为一个构造不是一个函数。他们是独立的实体。当你编写一个内建函数时,你不会编写一个需要参数的函数 - 内置函数的语法直接由解析器处理,并且被识别为内建函数,而不是函数。 (如果考虑具有一流功能的语言,这可能会更容易理解:实际上,您可以将对象作为对象传递给函数,而不能使用内置函数来实现。)

I know that include, isset, require, print, echo, and some others are not functions but language constructs.

Some of these language constructs need parentheses, others don't.

require 'file.php';
isset($x);

Some have a return value, others do not.

print 'foo'; //1
echo  'foo'; //no return value

So what is the internal difference between a language construct and a built-in function?

解决方案

(This is longer than I intended; please bear with me.)

Most languages are made up of something called a "syntax": the language is comprised of several well-defined keywords, and the complete range of expressions that you can construct in that language is built up from that syntax.

For example, let's say you have a simple four-function arithmetic "language" that only takes single-digit integers as input and completely ignores order of operations (I told you it was a simple language). That language could be defined by the syntax:

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

From these three rules, you can build any number of single-digit-input arithmetic expressions. You can then write a parser for this syntax that breaks down any valid input into its component types ($expression, $number, or $operator) and deals with the result. For example, the expression 3 + 4 * 5 can be broken down as follows:

// 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

Now we have a fully parsed syntax, in our defined language, for the original expression. Once we have this, we can go through and write a parser to find the results of all the combinations of $number $operator $number, and spit out a result when we only have one $number left.

Take note that there are no $expression constructs left in the final parsed version of our original expression. That's because $expression can always be reduced to a combination of other things in our language.

PHP is much the same: language constructs are recognized as the equivalent of our $number or $operator. They cannot be reduced into other language constructs; instead, they're the base units from which the language is built up. The key difference between functions and language constructs is this: the parser deals directly with language constructs. It simplifies functions into language constructs.

The reason that language constructs may or may not require parentheses and the reason some have return values while others don't depends entirely on the specific technical details of the PHP parser implementation. I'm not that well-versed in how the parser works, so I can't address these questions specifically, but imagine for a second a language that starts with this:

$expression := ($expression) | ...

Effectively, this language is free to take any expressions it finds and get rid of the surrounding parentheses. PHP (and here I'm employing pure guesswork) may employ something similar for its language constructs: print("Hello") might get reduced down to print "Hello" before it's parsed, or vice-versa (language definitions can add parentheses as well as get rid of them).

This is the root of why you can't redefine language constructs like echo or print: they're effectively hardcoded into the parser, whereas functions are mapped to a set of language constructs and the parser allows you to change that mapping at compile- or runtime to substitute your own set of language constructs or expressions.

At the end of the day, the internal difference between constructs and expressions is this: language constructs are understood and dealt with by the parser. Built-in functions, while provided by the language, are mapped and simplified to a set of language constructs before parsing.

More info:

  • Backus-Naur form, the syntax used to define formal languages (yacc uses this form)

Edit: Reading through some of the other answers, people make good points. Among them:

  • A language builtin is faster to call than a function. This is true, if only marginally, because the PHP interpreter doesn't need to map that function to its language-builtin equivalents before parsing. On a modern machine, though, the difference is fairly negligible.
  • A language builtin bypasses error-checking. This may or may not be true, depending on the PHP internal implementation for each builtin. It is certainly true that more often than not, functions will have more advanced error-checking and other functionality that builtins don't.
  • Language constructs can't be used as function callbacks. This is true, because a construct is not a function. They're separate entities. When you code a builtin, you're not coding a function that takes arguments - the syntax of the builtin is handled directly by the parser, and is recognized as a builtin, rather than a function. (This may be easier to understand if you consider languages with first-class functions: effectively, you can pass functions around as objects. You can't do that with builtins.)

这篇关于语言结构和“内置”结构之间的区别是什么?函数在PHP中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆