diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 3cc509723425..ada5089ca791 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -1916,7 +1916,7 @@ static zend_op_array *file_cache_compile_file(zend_file_handle *file_handle, int HANDLE_BLOCK_INTERRUPTIONS(); SHM_UNPROTECT(); - persistent_script = zend_file_cache_script_load(file_handle); + persistent_script = zend_file_cache_script_load(file_handle, false); SHM_PROTECT(); HANDLE_UNBLOCK_INTERRUPTIONS(); if (persistent_script) { @@ -2133,7 +2133,7 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) /* Check the second level cache */ if (!persistent_script && ZCG(accel_directives).file_cache) { - persistent_script = zend_file_cache_script_load(file_handle); + persistent_script = zend_file_cache_script_load(file_handle, false); } /* If script was not found or invalidated by validate_timestamps */ diff --git a/ext/opcache/opcache.stub.php b/ext/opcache/opcache.stub.php index 526da238219a..a509dff7ecac 100644 --- a/ext/opcache/opcache.stub.php +++ b/ext/opcache/opcache.stub.php @@ -22,4 +22,4 @@ function opcache_jit_blacklist(Closure $closure): void {} */ function opcache_get_configuration(): array|false {} -function opcache_is_script_cached(string $filename): bool {} +function opcache_is_script_cached(string $filename, bool $file_cache = false): bool {} diff --git a/ext/opcache/opcache_arginfo.h b/ext/opcache/opcache_arginfo.h index b4dc1f33a5fd..f42b392cbdb1 100644 --- a/ext/opcache/opcache_arginfo.h +++ b/ext/opcache/opcache_arginfo.h @@ -24,7 +24,10 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_opcache_get_configuration, 0, 0, MAY_BE_ARRAY|MAY_BE_FALSE) ZEND_END_ARG_INFO() -#define arginfo_opcache_is_script_cached arginfo_opcache_compile_file +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_opcache_is_script_cached, 0, 1, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, file_cache, _IS_BOOL, 0, "false") +ZEND_END_ARG_INFO() ZEND_FUNCTION(opcache_reset); ZEND_FUNCTION(opcache_get_status); diff --git a/ext/opcache/zend_accelerator_module.c b/ext/opcache/zend_accelerator_module.c index 1b62b757b87d..a3343870ed6f 100644 --- a/ext/opcache/zend_accelerator_module.c +++ b/ext/opcache/zend_accelerator_module.c @@ -27,6 +27,7 @@ #include "zend_closures.h" #include "zend_shared_alloc.h" #include "zend_accelerator_blacklist.h" +#include "zend_file_cache.h" #include "php_ini.h" #include "SAPI.h" #include "zend_virtual_cwd.h" @@ -363,6 +364,33 @@ static int filename_is_in_cache(zend_string *filename) return 0; } +static int filename_is_in_file_cache(zend_string *filename) +{ + if (!ZCG(accel_directives).file_cache) { + return 0; + } + + zend_file_handle *handle; + + zend_stream_init_filename_ex(handle, filename); + + if (!handle->opened_path) { + zend_destroy_file_handle(handle); + return 0; + } + + zend_persistent_script *persistent_script = zend_file_cache_script_load(handle, true) + + zend_destroy_file_handle(handle); + + if (persistent_script) { + return 1; + } + + return 0; +} + + static int accel_file_in_cache(INTERNAL_FUNCTION_PARAMETERS) { if (ZEND_NUM_ARGS() == 1) { @@ -983,10 +1011,11 @@ ZEND_FUNCTION(opcache_compile_file) ZEND_FUNCTION(opcache_is_script_cached) { zend_string *script_name; + bool file_cache = 0; - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STR(script_name) - ZEND_PARSE_PARAMETERS_END(); + if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|b", &script_name, &file_cache) == FAILURE) { + RETURN_THROWS(); + } if (!validate_api_restriction()) { RETURN_FALSE; @@ -996,5 +1025,9 @@ ZEND_FUNCTION(opcache_is_script_cached) RETURN_FALSE; } - RETURN_BOOL(filename_is_in_cache(script_name)); + if (file_cache) { + RETURN_BOOL(filename_is_in_file_cache(script_name)); + } else { + RETURN_BOOL(filename_is_in_cache(script_name)); + } } diff --git a/ext/opcache/zend_file_cache.c b/ext/opcache/zend_file_cache.c index fe54c477cea7..74a643f1e42b 100644 --- a/ext/opcache/zend_file_cache.c +++ b/ext/opcache/zend_file_cache.c @@ -1813,7 +1813,7 @@ static void zend_file_cache_unserialize(zend_persistent_script *script, zend_file_cache_unserialize_early_bindings(script, buf); } -zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handle) +zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handle, bool force_file_cache_only) { zend_string *full_path = file_handle->opened_path; int fd; @@ -1928,6 +1928,7 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl } if (!file_cache_only && + !force_file_cache_only && !ZCSG(restart_in_progress) && !ZCSG(restart_pending) && !ZSMMG(memory_exhausted) && diff --git a/ext/opcache/zend_file_cache.h b/ext/opcache/zend_file_cache.h index 8f067f5f37ab..30eb1a18b60e 100644 --- a/ext/opcache/zend_file_cache.h +++ b/ext/opcache/zend_file_cache.h @@ -20,7 +20,7 @@ #define ZEND_FILE_CACHE_H int zend_file_cache_script_store(zend_persistent_script *script, bool in_shm); -zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handle); +zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handle, bool force_file_cache_only); void zend_file_cache_invalidate(zend_string *full_path); #endif /* ZEND_FILE_CACHE_H */