PHP fopen()权限问题求助:全网未找到有效解决方案
Let's work through this super common permission issue step by step—this comes up all the time when setting up file-based logging with libraries like KLogger.
First, let's recap the error we're targeting to stay focused:
Warning: fopen(/var/www/html/includes/../log/404/log_2018-04-07.txt): failed to open stream: Permission denied in /var/www/html/vendor/katzgrau/klogger/src/Logger.php on line 167
Fatal error: Uncaught exception 'RuntimeException' with message 'The file could not be opened. Check permissions.' in /var/www/html/vendor/katzgrau/klogger/src/Logger.php:134
Here's what to check and fix:
1. Make sure the target directory exists
Sometimes the "permission denied" error is misleading—if the /var/www/html/log/404/ directory doesn't exist at all, PHP can't create the log file there. Run this command to verify:
ls -ld /var/www/html/log/404/
If it returns "No such file or directory", create the directory recursively (so it makes parent directories if needed):
mkdir -p /var/www/html/log/404/
2. Fix directory/file ownership
PHP runs under a specific system user (usually www-data for Apache/Nginx on Debian/Ubuntu, apache on CentOS/RHEL). This user needs read/write access to the log directory and files.
First, figure out which user PHP is running as:
- For PHP-FPM: Run
ps aux | grep php-fpmand look at the "USER" column - For Apache mod_php: Run
ps aux | grep apacheto find the user
Assuming the user is www-data, set the ownership of the entire log directory:
chown -R www-data:www-data /var/www/html/log/
3. Set secure permissions
Never use 777 (world-writable)—it's a massive security risk. Stick to these safe settings:
- Set directory permissions to
755(read/write/execute for owner, read/execute for others):chmod -R 755 /var/www/html/log/ - If the log file already exists, set its permissions to
644(read/write for owner, read for others):chmod 644 /var/www/html/log/404/log_2018-04-07.txt
4. Check SELinux (for RHEL/CentOS systems)
SELinux often blocks web servers from writing to directories even if file permissions are correct. To test if SELinux is the culprit, temporarily disable it:
setenforce 0
If the error goes away, permanently allow Apache/PHP to write to the log directory with:
chcon -R -t httpd_sys_rw_content_t /var/www/html/log/
5. Verify open_basedir restrictions
PHP's open_basedir setting limits which directories PHP can access. Check if /var/www/html/log/ is in the allowed list:
- Look for the
open_basedirdirective in yourphp.inifile - Or create a quick test file with
<?php phpinfo(); ?>, access it in your browser, and search for "open_basedir"
If it's missing, add it to the list and restart your PHP/Apache/Nginx service.
Quick sanity check
Just to confirm: the relative path in your code (../log/404/) resolves correctly from /var/www/html/includes/ to /var/www/html/log/404/, which matches the path in the error. So that part is working as intended.
内容的提问来源于stack exchange,提问作者Omer

