I am trying to add a mechanism for loading classes on demand and then basically unloaded them / being able to reload them. Essentially, each time the class is needed, it should be loaded freshly from disk as opposed to using what already exists in memory.
To do so, I am following the instructions here: Reloading a Class
However, I have noticed some odd behavior:
file2.php:
class OtherClass {
public function doSomething() {
echo "Hello, goodbye";
}
}
file.php:
class MyClass {
public function myFunction() {
print_r(get_declared_classes());
$pid = pcntl_fork();
if ($pid === -1) {
/* fork failed */
} else if ($pid > 0) { /* parent */
pcntl_wait($status);
print_r(get_declared_classes());
} else { /* the child */
echo "Loading class";
require("file2.php"); /* load the class */
OtherClass::doSomething();
}
}
}
As would be required, the require
executes only when the function is called, not when the file itself is loaded by PHP. So this means that prior to that line of code being executed when the function is called, which would be after the fork, that class doesn't exist.
As such, I would expect that when the second print_r
executes, it is exactly the same output as the first time. This is because the child has loaded the class, not the parent.
However, what actually happens is that the class that was loaded by the child has somehow has become visible to the parent process. (The second print_r
has the class that the child loaded and is now larger.)
Am I missing something here? When the program forked, this other class didn't exist. The child loaded it and used it, and then died; yet, that class is now visible to the parent.
The real problem here is that the next time the function executes, loading the class again using require
fails because the class already exists. This would be expected if the class existed in the parent process at the time it was forked. This means that somehow, the class "leaked" from the child process to the parent process.
My understanding is that once the fork happens, stuff in the child shouldn't affect the parent, outside of sharing file descriptors like STDOUT, so why is this happening? How can I achieve the "expected result"? At the moment, this allows loading a class later during program execution, but it can only be done once, as opposed to multiple times. I don't see anything in the PHP docs for this function that would explain this behavior.
require
andinclude
are expressions, just likeecho
; they're not function calls. Adding parentheses will work, but is not the right way to use these. Just like yourecho "Loading class";
, userequire "file2.php";
.