bmacnaughton
bmacnaughton

Reputation: 5308

What does each pass of the PHP interpreter process?

I have an include file that defines a class then creates a global with an instantiation of that class as well as a function that returns the global (for access within other functions).

Code-wise:

class X {
    ...
}

global $x;
$x = new X();

function x() {
    global $x;
    return $x;
}

So far everything seemed fine. Then there was a situation where (apparently) this file was included more than once - it's done by a framework so I can't limit it to include_once - which created an error attempting to redefine the class.

So I added code at the top:

if (class_exists('X')) {
    return;
}

And I found that $x was no longer defined. So it seems that the interpreter must run through once, find the class definition, but not process the statements following that. Then it seems like it makes a second pass and finds that the class exists, so it returns without ever executing the class instantiation.

So I changed the code at the top to:

if (class_exists('X')) {
    global $x;
    $w = new X();

    function x() {
        global $x;
        return $x;
    }
    return;
}

And now I get an error trying to redeclare the function (the original declaration is still at the bottom of the file). So it seems like even though the code to instantiate X was not executed the function was defined.

So the top of the file now looks like this:

if (class_exists('X')) {
    global $x;
    $w = new X();

    if (function_exists('x')) {
        return;
    }

    function x() {
        global $x;
        return $x;
    }
    return;
}

So now everything works as it seems like it should.

Based on what I've seen my best guess is that the interpreter makes a pass that collects class and function definitions then makes another pass that executes code using those definitions. Is this interpretation correct? Are there nuances that I am missing?

I'm not an expert PHP programmer by any means, so any information is appreciated.

Upvotes: 3

Views: 163

Answers (1)

A.L
A.L

Reputation: 10503

Then there was a situation where (apparently) this file was included more than once - it's done by a framework so I can't limit it to include_once

Then you can split your code in two files:

  1. Add include_once in the file that can be called several times
  2. Move the X class in another file, this new fille will be included by the include_once added in 1.

With this, the 2. file will be included only once, even if the 1. file is called several times.

You should probably use require_once (instead of include_once) because it will return an error if the file is not found.

Upvotes: 1

Related Questions