I feel silly asking but can I check with the experts about the behaviour of including inside a class method.
When I use require_once
to include class definition files inside a class method are there any gotchas I need to be aware of. I am thinking of an autoloading method on a factory class but really any time the a method does include or require.
My expectation is that it should be exactly the same as if I had simply included them at the start in, say, an include file. Am I right? I only ask as when you include a file in a class method it inherits the method scope.
One thing to watch out for is scoping of global variables. By example:
File: a.php
<?php
$foo = 'bar';
File: b.php
<?php
require_once 'a.php';
echo $foo;
File: c.php
<?php
load_foo();
show_foo();
function load_foo() {
require_once 'a.php';
}
function show_foo() {
require_once 'b.php';
}
Now if you run b.php
directly (e.g. php b.php
) you will get the proper output:
bar
However, if you run c.php
you get this:
PHP Notice: Undefined variable: foo in C:\temp\b.php on line 3
PHP Stack trace:
PHP 1. {main}() C:\temp\c.php:0
PHP 2. show_foo() C:\temp\c.php:3
PHP 3. require_once() C:\temp\c.php:9
The reason for the error is that inside c.php
we load a.php
within the function load_foo()
. This causes the variable $foo
to be scoped as a local variable for function load_foo()
whereas otherwise it would be a global variable. Then when show_foo()
is called it loads b.php
, which skips the require_once
(since we already loaded a.php
) and then tries to print $foo
. But it can't, because $foo
isn't defined anymore. It went out of scope when we load_foo()
exited.
So, bringing it back to your original question - if you use autoload and the autoload happens in a function/method context, global variables are going to be scoped locally as in the example above. If you absolutely need to use global variables, make sure you use the global
keyword before you define them (that would be global $foo
as the first line of a.php
above) and before you use them (again, global $foo
after the require_once
in b.php
).