PHP включает семантику

Я пытаюсь понять, как интерпретировать конструкцию include PHP , например, является ли это текстовое включение, когда оно оценивается и т. Д. Как обычно, документация довольно неформальная и неопределенная.

Основываясь на экспериментах, он кажется синтаксическим сахаром. В частности, конструкция

 include 'Baz.php' 

является выражением, которое можно заменить на

 eval('?>' . file_get_contents('Baz.php', FILE_USE_INCLUDE_PATH)) 

Это верно? Является ли эта замена правильной в общем случае или только в моих тестах?

Редактировать: как примечания bwoebi, это обычно не так, поскольку у eval uated code нет одинаковых __FILE__ и __FILE__ магических констант. Если бы их можно было установить, мы могли бы также моделировать это.

Edit 2: этот вопрос является дубликатом этого: Equivalent of include использует eval . Тем не менее, все ответы там, кажется, опускают точку bwoebi о контексте пути к файлу.

Да, это должно быть в целом верно.

Единственные отличия:

  • файловый контекст (теперь eval()'ed code , а не код из этого файла)
  • относительные пути: когда вы включаете файлы в другие каталоги и используете их относительные пути, то файл, на который он указывает, теперь больше не может быть найден
  • file_get_contents() не зависит от установки allow_url_include ini (хотя allow_url_fopen влияет на оба)

Другие примечания:

  • Это нарушит кеширование PHP Opcode, так как содержимое файла будет считаться в памяти как текст, а затем проанализировано / оценено, что приведет к значительным ударам по производительности, если вы этого не ожидаете. Как упоминалось в этом вопросе .
  • Ошибки анализа в коде не будут фатальными для остальной части скрипта, что имеет побочный эффект, позволяющий продолжить выполнение скрипта, даже если логика, которая, как ожидается, произойдет, может не иметь. (Это может быть справедливо и для других типов ошибок).
  • Сообщение об ошибках не будет разрешено для правильного файла / строки, поэтому отладка станет затруднительной.
  • Это не будет поддерживать конструкцию _once , которая позволяет включать / требовать файлы строго один раз. Это означает, что повторяющиеся объявления класса / функции будут фатальными и / или ведут себя неожиданно.

Я уверен, что есть и другие соображения, которые делают это нецелесообразным. Не зная желаемой функциональности или причины, по которой вам нужно это сделать, дать вам полезный ответ сложно.

Наилучшая часть использования eval – это восстановление от ошибок (если вы могли бы назвать это «лучшей» вещью). Если это то преимущество, которое вы пытаетесь использовать, однако, это ваш единственный вариант … К сожалению …