Bug #79956 [Com]: include_once ignores preloading
| From: | crell@php.net | Date: | Mon, 17 Aug 2020 21:54:21 +0000 |
| Subject: | Bug #79956 [Com]: include_once ignores preloading | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-228629@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=79956&edit=1
ID: 79956
Comment by: crell@php.net
Reported by: crell@php.net
Summary: include_once ignores preloading
Status: Open
Type: Bug
Package: opcache
Operating System: Linux
PHP Version: 7.4.9
Block user comment: N
Private report: N
New Comment:
That is indeed a complicating factor. I'll note that in the docs.
Still, this behavior of require_once() seems incorrect. I guess we have a choice:
1) _once() doesn't mean once for preloading, but blindly including files with constants still
works. (No idea what the performance impact is here.)
2) _once() works, but caveat emptor if there are constants defined. If there are, you need to use
require() instead.
I'm not sure which I favor.
Previous Comments:
------------------------------------------------------------------------
[2020-08-12 07:56:12] nikic@php.net
A complication here is probably that preloading cannot load everything. If you require_once'd
file contains constant definitions, you'd still want those to be executed during the request.
> I don't entirely understand how that combination of results can happen, as it implies the
> file is being executed twice but not dying on the already-declared function.
Preloading removes the parts of the code that it successfully preloaded.
------------------------------------------------------------------------
[2020-08-11 21:09:16] crell@php.net
Description:
------------
The list of include/require_once()'ed files seems to not persist between preloading and regular
code run.
Given the 3 files in the test script section, if I run the following:
php -d opcache.preload=preload.php -S localhost:8080
And then view the page in a browser, I would expect to just see "A" in the output.
Instead, I see:
Including A
A
Indicating the file is really getting executed twice; once in preload, once in the page request.
However, there's no error about the function already being defined.
The "Including A" line is shown on the console when the server starts, indicating it is
preloading the file. If I remove the require_once() from index.php, the code still runs, confirming
it is getting preloaded.
I don't entirely understand how that combination of results can happen, as it implies the file
is being executed twice but not dying on the already-declared function.
Test script:
---------------
<?php
# a.php
print "Including A" . PHP_EOL;
function a() {
print "A" . PHP_EOL;
}
?>
<?php
# preload.php
require_once('a.php');
?>
<?php
# index.php
header('content-type: text/plain');
require_once('a.php');
a();
?>
Expected result:
----------------
The behavior I would expect is that a file require_once()ed in preload would get skipped entirely if
require_once()ed again in the main application. That way, I'd be able to have my application
require_once() all of the non-autoloadable files it needs, but then still toss all of that into
preloading for production and have it just "get faster." Whatever is happening in those
files should only happen the one time, period.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=79956&edit=1