diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 19c7f35ff5982..6aa96f07a71d1 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -3608,6 +3608,7 @@ static zend_op_array *preload_compile_file(zend_file_handle *file_handle, int ty //??? efree(op_array->refcount); op_array->refcount = NULL; + script->script.main_op_array.fn_flags |= ZEND_ACC_PRELOADED; zend_hash_add_ptr(preload_scripts, script->script.filename, script); } @@ -4581,6 +4582,31 @@ static int accel_preload(const char *config, bool in_child) return ret; } +bool accel_is_script_preloaded(zend_string *script_name) +{ + if (CG(compiler_options) & ZEND_COMPILE_PRELOAD) { + if (preload_scripts) { + return zend_hash_exists(preload_scripts, script_name); + } + } else { + zend_string *key; + + if (!ZCG(accelerator_enabled) || !ZCSG(preload_script)) { + return false; + } + + key = accel_make_persistent_key(script_name); + if (key != NULL) { + zend_persistent_script *persistent_script = zend_accel_hash_find(&ZCSG(hash), key); + if (persistent_script && (persistent_script->script.main_op_array.fn_flags & ZEND_ACC_PRELOADED)) { + return true; + } + } + } + + return false; +} + static size_t preload_ub_write(const char *str, size_t str_length) { return fwrite(str, 1, str_length, stdout); diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h index 824e3cd3575fd..1912b9a4b5110 100644 --- a/ext/opcache/ZendAccelerator.h +++ b/ext/opcache/ZendAccelerator.h @@ -313,6 +313,8 @@ void accelerator_shm_read_unlock(void); zend_string *accel_make_persistent_key(zend_string *path); zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type); +bool accel_is_script_preloaded(zend_string *script_name); + #define IS_ACCEL_INTERNED(str) \ ((char*)(str) >= (char*)ZCSG(interned_strings).start && (char*)(str) < (char*)ZCSG(interned_strings).top) diff --git a/ext/opcache/opcache.stub.php b/ext/opcache/opcache.stub.php index ba65b9a264db3..84c2dc6910362 100644 --- a/ext/opcache/opcache.stub.php +++ b/ext/opcache/opcache.stub.php @@ -13,3 +13,5 @@ function opcache_invalidate(string $filename, bool $force = false): bool {} function opcache_get_configuration(): array|false {} function opcache_is_script_cached(string $filename): bool {} + +function opcache_is_script_preloaded(string $filename): bool {} diff --git a/ext/opcache/opcache_arginfo.h b/ext/opcache/opcache_arginfo.h index 55e867f392906..f61abb68af6c0 100644 --- a/ext/opcache/opcache_arginfo.h +++ b/ext/opcache/opcache_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 919d85eb3f3e1127ea3911051f1d98340e84654e */ + * Stub hash: 83af45063d21f90e3736045a9703f27480a587ad */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_opcache_reset, 0, 0, _IS_BOOL, 0) ZEND_END_ARG_INFO() @@ -22,6 +22,8 @@ ZEND_END_ARG_INFO() #define arginfo_opcache_is_script_cached arginfo_opcache_compile_file +#define arginfo_opcache_is_script_preloaded arginfo_opcache_compile_file + ZEND_FUNCTION(opcache_reset); ZEND_FUNCTION(opcache_get_status); @@ -29,6 +31,7 @@ ZEND_FUNCTION(opcache_compile_file); ZEND_FUNCTION(opcache_invalidate); ZEND_FUNCTION(opcache_get_configuration); ZEND_FUNCTION(opcache_is_script_cached); +ZEND_FUNCTION(opcache_is_script_preloaded); static const zend_function_entry ext_functions[] = { @@ -38,5 +41,6 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(opcache_invalidate, arginfo_opcache_invalidate) ZEND_FE(opcache_get_configuration, arginfo_opcache_get_configuration) ZEND_FE(opcache_is_script_cached, arginfo_opcache_is_script_cached) + ZEND_FE(opcache_is_script_preloaded, arginfo_opcache_is_script_preloaded) ZEND_FE_END }; diff --git a/ext/opcache/zend_accelerator_module.c b/ext/opcache/zend_accelerator_module.c index da1696bb92083..c5e402e459864 100644 --- a/ext/opcache/zend_accelerator_module.c +++ b/ext/opcache/zend_accelerator_module.c @@ -923,3 +923,19 @@ ZEND_FUNCTION(opcache_is_script_cached) RETURN_BOOL(filename_is_in_cache(script_name)); } + +/* {{{ Return true if the script is preloaded in OPCache, false if it is not cached or if OPCache is not running. */ +ZEND_FUNCTION(opcache_is_script_preloaded) +{ + zend_string *script_name; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(script_name) + ZEND_PARSE_PARAMETERS_END(); + + if (!validate_api_restriction()) { + RETURN_FALSE; + } + + RETURN_BOOL(accel_is_script_preloaded(script_name)); +}