14

I'm wondering about order of interpreting function declarations by PHP engine. I don't know why somethimes PHP shows Call to undefined function fatal error and somethimes interpreter see the function without problem.

Let's suppose my code is:

echo theRest(4,3);

function theRest($a, $b)
{
   return $a % $b;
}

See that function is declared after invocation and this works proper. It means that PHP reads whole file before interpretation?

Another example:

echo theRest(4,3);

include('test2.php');

test2.php

function theRest($a, $b)
{
    return $a % $b;
}

Here i'm getting the Fatal error: Call to undefined function theRest(). Why is that?

webrama.pl
  • 1,870
  • 1
  • 23
  • 36
  • Deleted my earlier post because the first one DID work on my machine. (I got 1) Hope somebody can provide the answer too. – Scott Yang Mar 11 '13 at 09:33
  • Take a look at this [Question](http://stackoverflow.com/questions/5762017/php-include-not-working-function-not-being-included) could it be a similar problem? And, by the way, does PHP give you -any- error, if you just put the `include('test2.php');` row -before- that function? You know, just to try it out :) – Erenor Paz Mar 11 '13 at 09:40
  • This was mentioned on the [YourLanguageSucks](https://wiki.theory.org/YourLanguageSucks#PHP_sucks_because:) wiki page – Marko D Mar 11 '13 at 09:42

3 Answers3

9

means that PHP is reading whole file before interpretation?

yes, PHP parses one file at a time. And "include" is a statement, not something that happens at compile time, so the included file is parsed as soon as the include line is reached. Function definition on the other hand are not statements and are processed at compile time, except when they are located within a control structure. This is why the following works:

if (!function_exists('ucwords')) {
    function ucwords($str) {
        //...
    }
}

So every function and class definition in a file that has been parsed and resides outside of a control structure is available immediately.

Fabian Schmengler
  • 24,155
  • 9
  • 79
  • 111
8

When PHP reads a file, it compiles it to bytecode (compile time), then executes it (execution time / runtime).

Unconditional function declarations are read at compile time, so that functions are already known when your code is executed.

Includes, on the other hand, are executed at execution time, so functions defined in the include file are not available before the include() itself is executed. Includes cannot be performed at compile time, since the argument may be dynamic (e.g. include $path_to_file;) and depend on the include_path setting that may be modified by your code.

The documentation is quite clear about that:

Functions need not be defined before they are referenced, except when a function is conditionally defined as shown in the two examples below.

When using include(), your function is de-facto conditionally defined (for example, include "foo.php"; can include one file or the other depending on the include_path setting).

Ferdinand Beyer
  • 64,979
  • 15
  • 154
  • 145
  • Thanks guys. I guess that means I will no longer move an "unconditional" function under and outside a conditional statement to squeeze that nonexistent processing time. – Scott Yang Mar 12 '13 at 23:02
0

In this code:

echo theRest(4,3);

function theRest($a, $b)
{
   return $a % $b;
}

The whole gets compiled first and then your code runs. However, in this code:

echo theRest(4,3);

include('test2.php');

The include statement itself is compiled but not executed until the code has reached that point of execution.

Placing the include before the point when it's referenced fixes it:

include('test2.php');

echo theRest(4,3);
Ja͢ck
  • 170,779
  • 38
  • 263
  • 309