Question

I am trying to work out how to interpret PHP's include construct, e.g. whether it is textual inclusion, when it is evaluated etc. As usual, the documentation is rather informal and vague.

Based on experimentation, it seems to be syntactic sugar. Specifically, the construct

include 'Baz.php'

is an expression which can be replaced with

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

Is this correct? Is this substitution true in the general case, or just in my tests?

Edit: as bwoebi notes, this is not generally true since the evaluated code does not have the same __DIR__ and __FILE__ magic constants. If there were some way to set them, we could model that too.

Edit 2: this question is a duplicate of this one: Equivalent of include using eval. However, all the answers there appear to omit bwoebi's point about the file path context.

Was it helpful?

Solution

Yes, that should be generally true.

The only differences are:

  • file context (it's now eval()'ed code, not code from that file)
  • relative paths: when you include files in other directories and they use theirselves relative paths, the file it points to might now not be found anymore
  • file_get_contents() is not affected by allow_url_include ini setting (though allow_url_fopen affect both)

OTHER TIPS

Other things to note are:

  • This will break PHP Opcode caching, as the file contents are read into memory as text, and then parsed/evaluated, producing a significant hit on performance if you are not expecting it. As mentioned in this question.
  • Parse errors in the code will not be fatal to the rest of the script, which has the side-effect of allowing the script execution to continue, even though logic that is expected to have happen may not have. (This may be true of other types of errors as well).
  • Error reporting will not resolve to the correct file/line, and therefore, debugging will become difficult.
  • This will not support the _once construct, which allows including/requiring files strictly once. This means duplicate class/function declarations will be fatal and/or behave unexpectedly.

I am certain there are other considerations that make this inadvisable as well. Without knowing your desired functionality or the reason you need to do this, giving you a helpful answer is difficult.

The best part of utilizing eval is the recovery from errors (if you could call this a "best" thing). If that is the benefit you are trying to take advantage of, however, this kind of is your only option.... Unfortunately...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top