Processing include/require directives in PHP

前端 未结 5 1380
广开言路
广开言路 2021-01-24 13:45

Background: I\'m building an automated test framework for a PHP application, and I need a way to efficiently \"stub out\" classes which encapsulate communicatio

5条回答
  •  不知归路
    2021-01-24 14:07

    According to php.net, if you use a return statement, it'll return execution to script that called it. Which means, require_once will stop executing, but the overall script will keep running. Also, examples on php.net show that if you return a variable within an included file, then you can do something like $foo = require_once('myfile.php'); and $foo will contain the returned value from the included file. If you don't return anything, then $foo is 1 to show that require_once was successful. Read this for more examples.

    And I don't see anything on php.net that says anything specifically about how the php interpreter will parse included statements, but your testing shows that it first resolves class definitions before executing code in-line.

    UPDATE

    I added some tests as well, by modifying Z.inc as follows:

        $test = new Z();
        echo $test->foo();
        if (defined ('MOCK_Z')) {
            return true;
        }
        class Z {
            function foo() {
                print "This is foo() from the original version of class Z.\n";
            }
        }
    

    And then tested on the command line as follows:

        %> php A.inc
        => This is foo() from a local version of class Z.
           This is foo() from a local version of class Z.
    
        %> php B.inc
        => This is foo() from the original version of class Z.
           This is foo() from the original version of class Z.
    

    Obviously, name hoisting is happening here, but the question remaining is why there are no complaints about re-declarations?

    UPDATE

    So, I tried to declare class Z twice in A.inc and I got the fatal error, but when I tried to declare it twice in Z.inc, I didn't get an error. This leads me to believe that the php interpreter will return execution to the file that did the including when a fatal runtime error occurs in an included file. That is why A.inc did not use Z.inc's class definition. It was never put into the environment, because it caused a fatal error, returning execution back to A.inc.

    UPDATE

    I tried the die(); statement in Z.inc, and it actually does stop all execution. So, if one of your included scripts has a die statement, then you will kill your testing.

提交回复
热议问题