Skip to content

Commit f455844

Browse files
authored
[3.x] Port improvements for opcache invalidation from CMS - redo PR #38 (#75)
* Invalidate opcache before deleting file Invalidate the OPCache for the file before actually deleting it. See https://www.php.net/manual/en/function.opcache-invalidate.php#116372 * Invalidate opcache of source before moving file * Invalidate opcache of temp file Invalidate opcache of uploaded temp file before saving to target file * Better check if opcache_invalidate is possible Check if - opcache is enabled, and - the opcache_invalidate function is available, and - calling opcache_invalidate is not restricted by opcache.restrict_api or it is restricted to allow the currently executing script and save the result in a static variable. * Remaining code style fix
1 parent 57f43b9 commit f455844

File tree

1 file changed

+47
-13
lines changed

1 file changed

+47
-13
lines changed

src/File.php

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@
1818
*/
1919
class File
2020
{
21+
/**
22+
* @var boolean true if OPCache enabled, and we have permission to invalidate files
23+
* @since 3.2.0
24+
*/
25+
protected static $canFlushFileCache;
26+
2127
/**
2228
* Gets the extension of a file name
2329
*
@@ -159,17 +165,25 @@ public static function delete($file)
159165
$file = Path::clean($file);
160166
$filename = basename($file);
161167

162-
// Try making the file writable first. If it's read-only, it can't be deleted
163-
// on Windows, even if the parent folder is writable
168+
/**
169+
* Try making the file writable first. If it's read-only, it can't be deleted
170+
* on Windows, even if the parent folder is writable
171+
*/
164172
@chmod($file, 0777);
165173

166-
// In case of restricted permissions we zap it one way or the other
167-
// as long as the owner is either the webserver or the ftp
174+
/**
175+
* Invalidate the OPCache for the file before actually deleting it
176+
* @link https://www.php.net/manual/en/function.opcache-invalidate.php#116372
177+
*/
178+
self::invalidateFileCache($file);
179+
180+
/**
181+
* In case of restricted permissions we zap it one way or the other
182+
* as long as the owner is either the webserver or the ftp
183+
*/
168184
if (!@ unlink($file)) {
169185
throw new FilesystemException(__METHOD__ . ': Failed deleting ' . $filename);
170186
}
171-
172-
self::invalidateFileCache($file);
173187
}
174188

175189
return true;
@@ -200,6 +214,8 @@ public static function move($src, $dest, $path = '', $useStreams = false)
200214
return 'Cannot find source file.';
201215
}
202216

217+
self::invalidateFileCache($src);
218+
203219
if ($useStreams) {
204220
$stream = Stream::getStream();
205221

@@ -294,6 +310,8 @@ public static function upload($src, $dest, $useStreams = false)
294310
Folder::create($baseDir);
295311
}
296312

313+
self::invalidateFileCache($src);
314+
297315
if ($useStreams) {
298316
$stream = Stream::getStream();
299317

@@ -321,21 +339,37 @@ public static function upload($src, $dest, $useStreams = false)
321339
}
322340

323341
/**
324-
* Invalidate any opcache for a newly written file immediately, if opcache* functions exist and if this was a PHP file.
342+
* Invalidate any opcache immediately for a file if opcache* functions are enabled and the file is a PHP file.
325343
*
326344
* @param string $file The path to the file just written to, to flush from opcache
327345
*
328346
* @return void
329347
*/
330348
public static function invalidateFileCache($file)
331349
{
332-
if (function_exists('opcache_invalidate')) {
333-
$info = pathinfo($file);
350+
/**
351+
* Check if we can invalidate the opcache. This is the case if
352+
* - opcache is enabled, and
353+
* - the opcache_invalidate function is available, and
354+
* - calling opcache_invalidate is not restricted by opcache.restrict_api
355+
* or it is restricted to allow the currently executing script
356+
*/
357+
if (!isset(static::$canFlushFileCache)) {
358+
static::$canFlushFileCache
359+
= ini_get('opcache.enable')
360+
&& \function_exists('opcache_invalidate')
361+
&& (!ini_get('opcache.restrict_api') || str_starts_with(realpath($_SERVER['SCRIPT_FILENAME']), ini_get('opcache.restrict_api')));
362+
}
334363

335-
if (isset($info['extension']) && $info['extension'] === 'php') {
336-
// Force invalidation to be absolutely sure the opcache is cleared for this file.
337-
opcache_invalidate($file, true);
338-
}
364+
if (!static::$canFlushFileCache) {
365+
return;
366+
}
367+
368+
$info = pathinfo($file);
369+
370+
if (isset($info['extension']) && $info['extension'] === 'php') {
371+
// Force invalidation to be absolutely sure the opcache is cleared for this file.
372+
opcache_invalidate($file, true);
339373
}
340374
}
341375
}

0 commit comments

Comments
 (0)