This guide shows you how to let a PHP script delete specific Nginx FastCGI cache files without compromising security or breaking your site. You’ll learn the exact configuration steps for Nginx, the PHP script logic, and the safety checks that prevent accidental deletion of unrelated files.
What You’ll Need
- Root or sudo access to your server (to edit Nginx and PHP-FPM configuration files).
- Nginx with FastCGI caching already configured and working.
- PHP-FPM running on the same server (or a socket that PHP can access).
- Basic familiarity with the command line and editing files via SSH.
Step-by-Step
- Identify your cache directory and key format. In your Nginx configuration, find the line that sets
fastcgi_cache_path. For example:fastcgi_cache_path /var/run/nginx-cache levels=1:2 keys_zone=MYCACHE:100m inactive=60m;. Note the path (/var/run/nginx-cache) and the levels (1:2). Also note thefastcgi_cache_keydirective; it defines how the cache key is built (e.g.,$scheme$request_method$host$request_uri). - Understand how Nginx maps keys to file paths. Nginx hashes the cache key with MD5, then splits the hash into directories according to the
levelssetting. Forlevels=1:2, the first character of the MD5 hash becomes a subdirectory, and the next two characters become a second-level subdirectory. The remaining characters are the filename. Example: hashabc123...becomes/var/run/nginx-cache/a/bc/abc123.... - Create a PHP script to delete a cache entry. The script must compute the MD5 hash of the exact cache key string that Nginx uses, then construct the file path and delete it only if it exists and is within the cache directory. Here’s a robust example:
<?php function delete_nginx_cache($cache_key, $cache_path, $levels) { $hash = md5($cache_key); $dir = $cache_path; $offset = 0; // Build directory structure based on levels, e.g., 1:2 foreach (explode(':', $levels) as $level) { $dir .= '/' . substr($hash, $offset, (int)$level); $offset += (int)$level; } $file = $dir . '/' . $hash; // Safety: ensure the resolved path is still inside the cache directory $real_base = realpath($cache_path); $real_file = realpath($file); if ($real_file === false || strpos($real_file, $real_base) !== 0) { return false; } if (is_file($real_file)) { return unlink($real_file); } return false; } // Example usage: $cache_key = 'GET' . 'https' . 'example.com' . '/page'; // Note: adjust the key to exactly match your fastcgi_cache_key directive. delete_nginx_cache($cache_key, '/var/run/nginx-cache', '1:2'); ?> - Match the cache key exactly. The most common mistake is mismatching the key. Look at your
fastcgi_cache_keydirective. If it is$scheme$request_method$host$request_uri, then for a request tohttps://example.com/pagewith GET method, the key isGEThttpsexample.com/page(no separators). Use the same concatenation in PHP. If your key includes variables like$http_accept_encoding, you must replicate that as well. - Set proper permissions for PHP-FPM. PHP-FPM runs as a specific user (e.g.,
www-data). That user must have read and write (delete) permissions on the cache directory. You can either change the owner of the cache directory to that user, or add the user to a group that owns the directory. For example:chown -R www-data:www-data /var/run/nginx-cache. But be careful: if Nginx also runs aswww-data, this is fine. If not, adjust accordingly. - Test with a known cache file. Create a test cache entry by visiting a page on your site, then find its corresponding file using the hash. You can compute the MD5 hash of the key in PHP or with command-line tools. Then run your PHP script and verify the file is gone.
- Integrate into your application. Call the PHP function whenever you update content that should invalidate its cached version (e.g., after saving a post). Make sure to construct the correct cache key for the URL that was updated.
- Consider using the
fastcgi_cache_purgedirective (if available). Nginx Plus and some open-source builds support thefastcgi_cache_purgedirective, which allows you to purge cache entries via a special request (e.g.,PURGEmethod). This is often simpler and safer, but it requires that your Nginx build includes the purge module. Check withnginx -V 2>&1 | grep purge. If available, you can configure a location block that handles PURGE requests and callsfastcgi_cache_purge.
Common Mistakes
- Incorrect cache key construction. The most common error. If the key doesn’t match exactly, the hash will be different, and the script will try to delete a non-existent file.
- Forgetting the levels structure. If your cache path uses
levels=1:2, you must replicate that in the PHP path builder. Using a flat path will fail. - Not checking realpath. Without the realpath check, a malicious or accidental input could cause the script to delete files outside the cache directory (e.g., if the cache key contains path traversal sequences).
- Permission errors. PHP-FPM may not have permission to delete files in the cache directory, especially if Nginx created them with a different user.
- Deleting while Nginx is writing. If you delete a file while Nginx is writing to it, you might leave a partial file. However, Nginx handles this gracefully by ignoring incomplete files, so it’s usually safe.
Tips
- Use a helper function. Centralize the cache deletion logic in a single PHP function or class so you can reuse it across your codebase.
- Log deletions. For debugging, log when you delete a cache file to a file or syslog. Include the cache key and the resulting file path.
- Cache key normalization. Ensure your cache key is normalized (e.g., lowercase host, remove trailing slashes) to avoid duplicate cache entries and mismatched deletions.
- Batch deletion. If you need to purge multiple URLs, loop through them, but be mindful of performance. Each deletion is a filesystem operation.
- Consider a cache tag system. For complex sites, implementing cache tags (e.g., using a header like
X-Cache-Tags) and a background script to purge by tag can be more efficient than purging individual URLs.
Troubleshooting
- File not deleted. Check the cache key by logging the computed hash and comparing it to the actual file in the cache directory. Also verify the file permissions and that the path is correct.
- Permission denied. Run
ls -lon the cache directory to see the owner and permissions. Adjust the PHP-FPM user or group accordingly. You may need to setchmod -R 775and add the PHP user to the group that owns the directory. - Cache still served after deletion. If you delete the file but the page still shows old content, it might be cached by the browser or by an upstream proxy. Also, Nginx might have a separate cache zone (e.g., for microcache) that you didn’t clear.
- PHP script works manually but not in web context. The web server user might have different permissions than your CLI user. Test with the same user that PHP-FPM uses.
- Nginx configuration changes not taking effect. After changing the cache key or path, remember to reload Nginx:
sudo nginx -s reload.
Frequently Asked Questions
Can I delete the entire cache directory with PHP?
Yes, but it’s not recommended. You can use exec('rm -rf /path/to/cache/*') but that’s risky and slow. Instead, use a loop with unlink and rmdir to clear it safely. Or better, use Nginx’s inactive parameter to let old entries expire naturally.
How do I find the cache key for a specific URL?
You can replicate the Nginx key construction in PHP. For example, if your key is $scheme$request_method$host$request_uri, then for a GET request to https://example.com/page, the key is GEThttpsexample.com/page. You can also add a temporary header to your Nginx config to log the key: add_header X-Cache-Key $fastcgi_cache_key; and then view the response headers.
Is it safe to delete a cache file while Nginx is reading it?
Yes, on Linux/Unix, deleting a file that is being read is safe. Nginx will continue to serve the content from the open file descriptor until it finishes, and subsequent requests will miss the cache and regenerate it.
What if I have multiple cache zones?
You need to handle each zone separately. The PHP script must know which zone (and its path and levels) to target. You can pass the zone name as a parameter to your function.
Can I use the PURGE method with open-source Nginx?
Only if your Nginx build includes the ngx_cache_purge module. Many distribution packages do not include it. You can check by running nginx -V 2>&1 | grep purge. If it’s not there, you’ll need to compile Nginx with the module or use the PHP method described above.
How do I prevent PHP from deleting files outside the cache directory?
Always use realpath() on both the base cache path and the constructed file path, and ensure the file path starts with the base path. Also, sanitize the cache key to avoid any path traversal characters like ../.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.
More cards in this drawer
- Mac Start Up Automatically After Power Failure?
- Expose Self-Hosted Service Securely Without Cloudflare Tunnel
- Nano Delivery for Functional Foods: What It Can and Can’t Do4.00
- Disable Apple Watch Turn-by-Turn Vibration While Driving
- Convert Play FLAC in iTunes: Full Guide
- Soda Foundation Charter: What It Means