Permission denied错误源于Web服务器运行用户与文件权限不匹配,需先确认实际用户(macOS查\_www,Windows查服务登录账户),再赋予think脚本执行权及runtime目录对应用户读写权限。

在macOS或Windows上运行ThinkPHP命令行或Web请求时突然报Permission denied,不是代码写错了,而是文件所有权、执行权限或Web服务器用户身份没对齐——macOS默认用_www用户跑PHP,Windows下IIS或XAMPP却常以SYSTEM或当前用户身份运行,同一套项目一换系统就卡在runtime目录写入失败或think脚本无法执行。
确认当前Web服务器实际运行用户
这一步漏掉,后面所有chmod都白做。Web进程不是你本人,它用谁的身份运行,就得把权限给谁。
macOS上执行:ps aux | grep -E '(php-fpm|httpd|apache)' | grep -v grep,看USER列是_www还是yourname;若用Homebrew安装的php-fpm,通常在/opt/homebrew/etc/php/*/php-fpm.d/www.conf里查user =和group =值。
Windows上打开“服务”管理器,找到Apache2.4或php-fpm服务,右键→属性→登录选项卡,看“此账户”填的是Local System、IIS_IUSRS还是你的用户名。
立即学习“PHP免费学习笔记(深入)”;
【必须记下这个用户名,后续所有chown或NTFS授权都要指向它】
修复think脚本与PHP二进制的执行权限
Linux/macOS下think是shell脚本,Windows下tp.bat是批处理,两者都必须有可执行位才能被php调用。
方法一(macOS/Linux):
进入项目根目录,运行chmod +x think;再检查ls -l think,确保权限列显示-rwxr-xr-x,否则PHP会直接报Permission denied。
方法二(Windows):
不要双击运行tp.bat,必须在管理员权限的PowerShell中执行php think run;若提示“不是内部或外部命令”,说明tp.bat所在路径(通常是vendor\bin)未加入系统PATH——右键“此电脑”→属性→高级系统设置→环境变量→在“系统变量”中找到Path→编辑→新建→粘贴%CD%\vendor\bin(部署时用绝对路径如C:\myapp\vendor\bin)。
在 Windows 11 上"直接发声"的 TTS(从 WSL2/TUI 调用 powershell.exe + System.Speech)。适用于用户说"说出来/读出来/语音播报/用TTS",或反馈"没声音/tts 生成的 mp3 是空的/播不出来",以及需要中文语音但 OpenClaw 内置 tts 不可用时。
注意:如果which php返回的PHP路径权限不对(如-rw-r--r--),运行sudo chmod +x $(which php)补执行位,否则php think会静默失败。
重置runtime等可写目录归属与权限
第一步:删除旧目录
执行rm -rf runtime/(macOS/Linux)或在资源管理器中彻底删除runtime文件夹(Windows)。
第二步:重建并赋权
macOS/Linux下运行:mkdir runtime && sudo chown -R _www:staff runtime(将_www换成你上一步确认的Web用户,staff是macOS通用组);
Windows下右键runtime→属性→安全→编辑→添加→输入IIS_IUSRS→勾选“完全控制”→确定。
第三步:验证写入能力
创建测试文件:echo "<?php echo 'ok';" > runtime/test.php(macOS/Linux),或在PowerShell中运行:"<?php echo 'ok';" | Out-File -FilePath .\runtime\test.php -Encoding UTF8(Windows)。若失败,说明权限仍未生效。
统一CLI与Web端PHP配置路径
1. 查CLI加载的php.ini:php --ini,记下“Loaded Configuration File”路径;
2. 启动Web服务,在浏览器访问phpinfo()页面,找“Loaded Configuration File”;
3. 若两者不一致,必须强制对齐:macOS上用sudo ln -sf /opt/homebrew/etc/php/8.3/php.ini /etc/php.ini(路径按实际版本调整);Windows上修改Apache的httpd.conf,确保PHPIniDir "C:/php81"指向CLI所用的同一目录。
关键点:opcache、error_log、date.timezone这些配置项在CLI和Web里必须相同,否则runtime缓存生成后Web端读不到,或日志全写到/tmp里找不到。
Windows下绕过UAC拦截启动内置服务器
第一步:以管理员身份运行PowerShell
右键开始菜单→Windows PowerShell(管理员)→确认弹窗允许。
第二步:进入项目根目录
执行cd C:\myapp,确认当前路径下存在think文件和vendor目录。
第三步:指定非特权端口启动
运行php think run -p 8080,不要用默认的8000——Windows下即使端口>1024,UAC仍可能拦截socket绑定;若仍报错,临时关闭Windows防火墙测试是否拦截。


















