Windows系统将phpEnv项目目录设为只读或防病毒软件(如BitDefender/Kaspersky)静默拦截写入,导致fopen() Permission denied;需取消文件夹只读属性、添加防病毒排除项、用icacls授予Users完全控制权,并重启Web服务。

phpEnv 项目目录被系统标记为只读,fopen() 报错 Permission denied
这不是 PHP 配置或 phpEnv 服务没启好的问题,而是 Windows 层面把整个站点文件夹(比如 D:\phpenv\www\myapp)设成了只读属性。哪怕你用管理员身份运行 phpEnv,fopen('log.txt', 'w') 依然会失败。
常见错误现象:Warning: fopen(log.txt): failed to open stream: Permission denied,且 is_writable() 返回 false,但目录明明是自己创建的。
- 右键点击该文件夹 → “属性” → 检查“只读”复选框是否被勾选(即使灰色也可能是继承自父目录)
- 若勾选了,取消勾选 → 点“应用” → 弹出对话框时选“将更改应用于此文件夹、子文件夹和文件”
- 特别注意:如果该目录在 OneDrive、Google Drive 同步文件夹内,同步客户端可能自动加只读标记,建议移出再试
防病毒软件拦截写入,尤其 BitDefender / Kaspersky 会静默设为只读
BitDefender 默认对非白名单进程打开的 PHP 文件(尤其是 .php 或日志类文件)强制以只读方式打开,不报错、不弹窗,但 PHP 就写不进去 —— 这是最难排查的一类。
验证方法:临时禁用实时防护,再运行一次 file_put_contents('test.txt', 'ok');若成功,就是它干的。
立即学习“PHP免费学习笔记(深入)”;
- BitDefender:打开控制中心 → “设置” → “高级设置” → “防病毒” → “排除项” → 添加你的 phpEnv 工作目录(如
D:\phpenv\www)和php.exe路径(如D:\phpenv\php\php.exe) - Kaspersky:设置 → “附加” → “受信任区域” → 添加文件夹,并勾选“允许修改文件”
- 其他厂商类似,关键词搜“exclusion”或“信任目录”
icacls 手动重置 NTFS 权限比右键属性更彻底
右键取消“只读”属性有时不生效,因为底层 NTFS 权限没给当前用户(比如 BUILTIN\Users 或你的登录账户)写入权。这时候得用命令行补一刀。
以管理员身份打开 CMD,执行:
icacls "D:\phpenv\www\myapp" /grant Users:F /t
说明:
-
Users:F表示授予内置 Users 组完全控制权(含写入),比只给W(写入)更稳妥 -
/t表示递归应用到所有子目录和文件 - 如果你用的是具体用户名(如
DESKTOP-ABC\Alice),把Users换成它即可 - 执行后若提示“处理 0 个文件”,说明路径有空格或中文,务必用英文引号包裹路径
phpEnv 自带的 Apache/Nginx 服务以 LocalSystem 运行,但实际写入的是你登录用户的上下文
很多人以为改了服务权限就行,其实不是:phpEnv 启动的 Web 服务默认以 LocalSystem 账户运行,但它调用 PHP 解释器执行脚本时,fopen 的文件操作仍受当前登录用户的 NTFS 权限约束 —— 尤其当文件由你手动创建、未显式赋权时。
- 最简方案:所有项目文件都由你本人新建(别从压缩包直接解压到目标目录),并确保新建后立即用
icacls赋权 - 避免用“复制粘贴”方式迁移项目,改用
robocopy /copyall或 7-Zip 解压,保留原始权限上下文 - 如果必须用解压包,解压后立刻进文件夹属性 → “安全”选项卡 → “编辑” → 给你的用户加“修改”权限
icacls,别忘了重启 phpEnv 的 Web 服务 —— 不是刷新浏览器,是真正停掉再启一次。



















