| | 2277 | |
| | 2278 | /** |
| | 2279 | * Attempt to clear the opcode cache for an individual PHP file. |
| | 2280 | * |
| | 2281 | * This function can be called safely without having to check the file extension |
| | 2282 | * or availability of the OPcache extension. |
| | 2283 | * |
| | 2284 | * Whether or not invalidation is possible is cached to improve performance. |
| | 2285 | * |
| | 2286 | * @since 5.5 |
| | 2287 | * |
| | 2288 | * @link https://www.php.net/manual/en/function.opcache-invalidate.php |
| | 2289 | * |
| | 2290 | * @param string $filepath Path to the file, including extension, for which the opcode cache is to be cleared. |
| | 2291 | * @param bool $force Invalidate even if the modification time is not newer than the file in cache. Default `false`. |
| | 2292 | * |
| | 2293 | * @return bool `true` if opcache was invalidated for `$filepath`, or there was nothing to invalidate. |
| | 2294 | * `false` if opcache invalidation is not available, or is disabled via filter. |
| | 2295 | */ |
| | 2296 | function wp_opcache_invalidate( $filepath, $force = false ) { |
| | 2297 | static $can_invalidate = null; |
| | 2298 | |
| | 2299 | /* |
| | 2300 | * Check to see if WordPress is able to run `opcache_invalidate()` or not, and cache the value. |
| | 2301 | * |
| | 2302 | * First, check to see if the function is available to call, then if the host has restricted |
| | 2303 | * the ability to run the function to avoid a PHP warning. |
| | 2304 | * |
| | 2305 | * `opcache.restrict_api` can specify the path for files allowed to call `opcache_invalidate()`. |
| | 2306 | * |
| | 2307 | * If the host has this set, check whether the path in `opcache.restrict_api` matches |
| | 2308 | * the beginning of the path of the origin file. |
| | 2309 | * |
| | 2310 | * `$_SERVER['SCRIPT_FILENAME']` approximates the origin file's path, but |
| | 2311 | * `realpath()` is necessary because `SCRIPT_FILENAME` can be a relative path |
| | 2312 | * when run from CLI. |
| | 2313 | * |
| | 2314 | * For more details, see: |
| | 2315 | * - https://www.php.net/manual/en/opcache.configuration.php |
| | 2316 | * - https://www.php.net/manual/en/reserved.variables.server.php |
| | 2317 | * - https://core.trac.wordpress.org/ticket/36455 |
| | 2318 | */ |
| | 2319 | if ( $can_invalidate === null ) { |
| | 2320 | $can_invalidate = function_exists( 'opcache_invalidate' ) && |
| | 2321 | ( ! ini_get( 'opcache.restrict_api' ) || |
| | 2322 | stripos( realpath( $_SERVER['SCRIPT_FILENAME'] ), ini_get( 'opcache.restrict_api' ) ) === 0 ); |
| | 2323 | } |
| | 2324 | |
| | 2325 | // If invalidation is not available, return early. |
| | 2326 | if ( ! $can_invalidate ) { |
| | 2327 | return false; |
| | 2328 | } |
| | 2329 | |
| | 2330 | // Verify that file to be invalidated has a PHP extension. |
| | 2331 | if ( ! preg_match( '/\.(?:php)$/i', $filepath ) ) { |
| | 2332 | return false; |
| | 2333 | } |
| | 2334 | |
| | 2335 | /** |
| | 2336 | * Filters whether to invalidate a file from the opcode cache. |
| | 2337 | * |
| | 2338 | * @since 5.5 |
| | 2339 | * |
| | 2340 | * @param bool $will_invalidate Whether WordPress will invalidate `$filename`. Default `true`. |
| | 2341 | * @param string $filename The PHP filename to invalidate. |
| | 2342 | */ |
| | 2343 | if ( apply_filters( 'wp_opcache_invalidate_file', true, $filepath ) ) { |
| | 2344 | return opcache_invalidate( $filepath, $force ); |
| | 2345 | } |
| | 2346 | |
| | 2347 | return false; |
| | 2348 | } |