Edit report at https://bugs.php.net/bug.php?id=79398&edit=1
ID: 79398
Updated by: cmb@php.net
Reported by: praszywka dot adam at gmail dot com
Summary: Different behavior of flock and include on PHP 7.3
and PHP 7.4
Status: Not a bug
Type: Bug
Package: *General Issues
Operating System: Windows 10 1909
PHP Version: 7.4.4
Assigned To: cmb
Block user comment: N
Private report: N
New Comment:
This is how LockFileEx[1] behaves:
| If the locking process opens the file a second time, it cannot
| access the specified region through this second handle until it
| unlocks the region.
|
| Locking a portion of a file for exclusive access denies all
| other processes both read and write access to the specified region
| of the file.
There is nothing PHP can do about that.
The fact that this worked prior to PHP 7.4.0 is related to using
mmap:
| Locking a region of a file does not prevent reading from a
| mapped file view.
But that mmap caused other issues, so had been changed, and like I
said, include/require now behave more like other file functions.
The flock() man page[2] needs more info regarding the Windows
peculiarities.
[1] <https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-lockfileex>
[2] <https://www.php.net/flock>
Previous Comments:
------------------------------------------------------------------------
[2021-07-04 04:03:50] dallas at ekkysoftware dot com
Just to follow that up, I have flock($file), then require($file). The flock is preventing the
require from reading the file, even though I am the same process.
------------------------------------------------------------------------
[2021-07-04 03:01:53] dallas at ekkysoftware dot com
This is a bug. Everything works in PHP7.3, but this issue shows up in PHP7.4.
require(): read of 25405 bytes failed with errno=13 Permission denied
On Windows there are no OS permissions to block the read, and in any case a permissions issue should
block the file open and not the file read. Also the '25405' is the correct filesize for
the included file, which shows the system can get stat the file, the path is correct and with
readable permissions.
------------------------------------------------------------------------
[2020-03-22 17:02:35] cmb@php.net
Okay, better reproducer:
<?php
$lock = fopen($cachePath, 'w');
fwrite($lock, '<?php echo "test\n";');
flock($lock, LOCK_EX);
include $cachePath;
?>
Anyhow, the behavioral change has been triggered by lexing no
longer using mmap()[1]; however, the new behavior is now in line
with other file functions, e.g.
<?php
$lock = fopen($cachePath, 'w');
fwrite($lock, '<?php echo "test\n";');
flock($lock, LOCK_EX);
echo file_get_contents($cachePath);
?>
On Windows, this produces no output (PHP 7.3 and 7.4). On Linux,
this usually prints the contents of the file. The relevant
difference is that flock() uses advisory locking on Linux by
default, while it is always mandatory on Windows.
So a reasonable fix for Symfony would be using a separate lock file,
like suggested by Nicolas[2].
[1] <http://git.php.net/?p=php-src.git;a=commit;h=5161cebe28cca36fa7f7989b5a799290a3f1eb6a>
[2] <https://github.com/symfony/symfony/issues/36132#issuecomment-601708409>
------------------------------------------------------------------------
[2020-03-21 21:34:19] praszywka dot adam at gmail dot com
That's the way how Symfony is currently creating cache.
Topic was stared here: https://github.com/symfony/symfony/issues/36132
It's not a standard way of using flock and include so I reported it as a incompatibility
between PHP < 7.{0,1,2,3} and 7.4.
That problem should be fixed in Symfony or PHP - it should be decided where.
------------------------------------------------------------------------
[2020-03-21 15:20:48] cmb@php.net
> PHP 7.3 allows to include previously locked file.
I'm confused, since opening the file in 'w' mode immediately
truncates it. Why would you include an empty file in the first
place?
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=79398
--
Edit this bug report at https://bugs.php.net/bug.php?id=79398&edit=1