Я знаю, что 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 := + | - | * | /
Из этих трех правил вы можете построить любое число арифметических выражений с одноразрядным входом. Затем вы можете написать синтаксический анализатор для синтаксиса, который разбивает любой допустимый ввод на его типы компонентов ( $expression
$number
, $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
Теперь у нас есть полностью проанализированный синтаксис на нашем определенном языке для исходного выражения. Как только мы это получим, мы можем пройти и написать синтаксический анализатор, чтобы найти результаты всех комбинаций $number $operator $number
и выплюнуть результат, когда у нас осталось только один $number
.
Обратите внимание, что в окончательной анализируемой версии нашего исходного выражения не осталось никаких выражений. Это потому, что $expression
всегда можно свести к сочетанию других вещей на нашем языке.
PHP очень похож: языковые конструкции распознаются как эквивалент нашего $operator
$number
или $operator
. Они не могут быть сведены к другим языковым конструкциям ; вместо этого они являются базовыми единицами, из которых выстраивается язык. Ключевое различие между функциями и языковыми конструкциями таково: парсер напрямую занимается языковыми конструкциями. Он упрощает функции в языковых конструкциях.
Причина, по которой языковые конструкции могут содержать или не содержать скобки, и причина, по которой некоторые имеют возвращаемые значения, а другие не полностью зависят от конкретных технических деталей реализации парсера PHP. Я не настолько хорошо разбираюсь в том, как работает парсер, поэтому я не могу конкретно ответить на эти вопросы, но представьте себе второй язык, который начинается с этого:
$expression := ($expression) | ...
Эффективно этот язык свободен принимать любые выражения, которые он находит, и избавляться от окружающих круглых скобок. PHP (и здесь я использую чистые догадки) может использовать что-то подобное для своих языковых конструкций: print("Hello")
может быть уменьшен до print "Hello"
перед его анализом или наоборот (определения языка могут добавлять скобки как а также избавиться от них).
Это корень причины, по которой вы не можете переопределять языковые конструкции, такие как echo
или print
: они эффективно жестко закодированы в синтаксический анализатор, тогда как функции сопоставляются с набором языковых конструкций, и синтаксический анализатор позволяет вам изменять это сопоставление при компиляции или чтобы заменить собственный набор языковых конструкций или выражений.
В конце дня внутренняя разница между конструкциями и выражениями такова: языковые конструкции понимаются и обрабатываются парсером. Встроенные функции, предоставляемые языком, сопоставляются и упрощаются до набора языковых конструкций перед разбором.
Больше информации:
Редактирование: прочитав некоторые другие ответы, люди делают хорошие очки. Среди них:
Языковые конструкции предоставляются самим языком (например, такие как «if», «while», …); отсюда их имя.
Одним из следствий этого является то, что они быстрее запускаются, чем предопределенные или определяемые пользователем функции (или так я слышал / читал несколько раз)
Я понятия не имею, как это делается, но одно, что они могут сделать (из-за того, что оно интегрировано непосредственно в langage) – это «обход» какого-то механизма обработки ошибок. Например, 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; это те, кто, вероятно, знал бы об этом. ^^
(И меня действительно интересуют другие ответы, btw ^^)
В качестве ссылки: список ключевых слов и языковых конструкций в PHP
После прошивки кода я обнаружил, что php анализирует некоторые из операторов в файле yacc. Так что это особые случаи.
(см. Zend / zend_language_parser.y)
Кроме того, я не думаю, что есть другие различия.
Вы можете переопределить встроенные функции . Ключевые слова навсегда.