
当 php 脚本在命令行或 web 环境中手动运行时 mkdir() 正常,但由 cron 定时执行时失败,通常源于工作目录、权限上下文或路径解析差异,而非单纯文件权限问题。
当 php 脚本在命令行或 web 环境中手动运行时 mkdir() 正常,但由 cron 定时执行时失败,通常源于工作目录、权限上下文或路径解析差异,而非单纯文件权限问题。
在 cron 环境下,PHP 进程默认以系统用户(如 root 或指定用户)身份运行,且当前工作目录(CWD)通常为用户的 home 目录(如 /root 或 /home/username),而非 Web 项目根目录(如 /var/www/html 或 /home/example.com/public_html)。因此,若代码中使用的是相对路径(例如 mkdir('20241201'))或未显式指定绝对路径,mkdir() 将尝试在错误位置创建目录,导致静默失败或权限拒绝。
此外,0777 权限掩码在 mkdir() 中仅作为 umask 的补充,并不等同于“强制设为 777”——实际创建权限还受系统 umask(如默认 0022)影响;更关键的是,父目录必须对执行用户具有写权限。即使目标路径权限设为 777,若其上级目录(如 /home/DOMAIN.COM/public_html)不可写,mkdir(..., true) 仍会失败。
✅ 正确做法是:始终使用绝对路径 + 显式指定完整目录结构。例如:
// ✅ 推荐:使用绝对路径,明确指向 Web 可写目录
$baseDir = '/home/DOMAIN.COM/public_html/results/';
$auxfile = date('Ymd'); // 如 '20241201'
$targetPath = $baseDir . $auxfile;
if (!file_exists($targetPath)) {
// 使用 0755 更安全(避免过度开放),true 启用递归创建
if (!mkdir($targetPath, 0755, true)) {
$error = error_get_last();
error_log("Failed to create directory {$targetPath}: " . ($error['message'] ?? 'Unknown error'));
// 可选:发送告警或记录到日志文件
}
}
⚠️ 注意事项:
- 不要依赖 @ 抑制错误:它掩盖了关键诊断信息。应启用错误报告并记录日志;
- 验证父目录可写性:在脚本开头添加 is_writable($baseDir) 检查;
- 确保 cron 用户拥有目标路径的写权限:如使用 www-data 用户运行 cron,则需 chown -R www-data:www-data /home/DOMAIN.COM/public_html/results/;
-
在 crontab 中显式指定 SHELL 和 PATH(可选但推荐):
SHELL=/bin/bash PATH=/usr/local/bin:/usr/bin:/bin * * * * * /usr/bin/php /home/DOMAIN.COM/public_html/scripts/daily_mkdir.php >> /home/DOMAIN.COM/logs/cron.log 2>&1
总结:cron 下 mkdir() 失败的本质是环境隔离性——它不继承 Web 服务器的路径、用户或权限上下文。解决核心在于路径绝对化、权限归属明确化、错误可观测化。忽略这一点而反复修改目标目录权限(如 chmod 777),往往治标不治本。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











