我知道include
、isset
、require
、print
、echo
和其他一些语言结构不是函数。
其中有些语言结构需要括号,而另一些则不需要。
require 'file.php';
isset($x);
有些函数有返回值,而其他函数没有。
print 'foo'; //1
echo 'foo'; //no return value
那么语言结构和内置函数之间的内在区别是什么?
我知道include
、isset
、require
、print
、echo
和其他一些语言结构不是函数。
其中有些语言结构需要括号,而另一些则不需要。
require 'file.php';
isset($x);
有些函数有返回值,而其他函数没有。
print 'foo'; //1
echo 'foo'; //no return value
那么语言结构和内置函数之间的内在区别是什么?
// The | means "or" and the := represents definition
$expression := $number | $expression $operator $expression
$number := 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
$operator := + | - | * | /
// 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
现在我们使用定义的语言完全解析了原始表达式的语法。一旦我们有了这个,我们就可以遍历所有$number $operator $number
组合的结果并输出一个结果,当我们只剩下一个$number
时。
注意,在我们原始表达式的最终解析版本中,没有任何$expression
结构。那是因为$expression
总是可以被简化成我们语言中的其他组合。
PHP也是如此:语言结构被认为是我们的$number
或$operator
等价物。它们不能被简化为其他语言结构,而是构建语言的基本单元。函数和语言结构之间的关键区别在于:解析器直接处理语言结构。它将函数简化为语言结构。
语言结构是否需要括号以及为什么有些具有返回值而其他一些则没有,取决于PHP解析器实现的具体技术细节。我对解析器的工作方式不是很熟悉,所以无法具体回答这些问题,但请想象一下一个从这里开始的语言:
$expression := ($expression) | ...
print("Hello")
可能会被缩减为 print "Hello"
,或者反过来(语言定义也可以添加括号,也可以去掉它们)。echo
或 print
这样的语言结构的根本原因:它们实际上是硬编码到解析器中的,而函数则映射到一组语言结构,并且解析器允许您在编译时或运行时更改该映射以替换您自己的语言结构或表达式。编辑:阅读其他答案时,有些人提出了很好的观点,其中包括:
语言结构是由语言本身提供的(比如像“if”、“while”这样的指令);因此它们被称为语言结构。
这种结构的一个结果是,它们的调用速度比预定义或用户定义的函数更快(或者我已经听说/读过好几次了)
我不知道具体怎么做,但它们可以做一些事情(由于直接集成到语言中),例如“绕过”某种错误处理机制。例如,isset()可以用于不存在的变量而不会导致任何通知、警告或错误。
function test($param) {}
if (test($a)) {
// Notice: Undefined variable: a
}
if (isset($b)) {
// No notice
}
*注意,并非所有语言的构造都是如此。
函数和语言构造之间的另一个区别是,一些语言构造可以像关键字一样无需使用括号进行调用。
例如:
echo 'test'; // language construct => OK
function my_function($param) {}
my_function 'test'; // function => Parse error: syntax error, unexpected T_CONSTANT_ENCAPSED_STRING
同样的,在许多语言构造中并非如此。
我想,绝对没有办法“禁用”语言构造,因为它们是语言本身的一部分。另一方面,许多“内置”的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
目前我脑海中没有其他想法... 而且我对PHP的内部机制不是很了解... 所以就先这样吧 ^^
如果你在这里得不到太多回答,也许你可以向内部邮件列表询问(请参见http://www.php.net/mailing-lists.php),那里有许多PHP核心开发人员;他们可能是了解这些问题的人^^
(顺便说一句,我真的很期待其他的答案^^)
参考文献:PHP中的关键字和语言结构列表
在深入阅读代码后,我发现php解析了yacc文件中的一些语句。因此它们是特殊情况。
(请参见Zend / zend_language_parser.y)
除此之外,我认为没有其他区别。
你可以覆盖内置函数。关键字是永恒的。