
PHP 脚本中 mkdir() 手动执行正常但 Cron 下失败,主因是 Cron 运行时工作目录和用户环境不同,导致相对路径失效或权限上下文异常;正确做法是始终使用绝对路径并显式指定完整目标路径。
php 脚本中 `mkdir()` 手动执行正常但 cron 下失败,主因是 cron 运行时工作目录和用户环境不同,导致相对路径失效或权限上下文异常;正确做法是始终使用绝对路径并显式指定完整目标路径。
在 PHP 中调用 mkdir() 创建每日目录(如 /20241201)时,若脚本通过 Web 服务器(如 Apache)访问能成功,但由系统 Cron 执行却静默失败,根本原因通常不是文件权限(即使设为 0777 也无效),而是路径解析上下文差异:
- Web 环境下,脚本常以网站根目录(如 /var/www/html/ 或 /home/user/public_html/)为当前工作目录,相对路径可能“碰巧”可解析;
- Cron 默认以用户家目录(如 /root 或 /home/username)为工作目录,且不加载 shell 配置(如 ~/.bashrc),$_SERVER['DOCUMENT_ROOT'] 等变量不可用,./ 或 ../ 类相对路径极易指向错误位置。
✅ 正确实践:强制使用绝对路径
修改你的代码,明确拼接完整、可复用的绝对路径:
// ✅ 推荐:基于真实文档根目录或项目部署路径构建绝对路径
$base_dir = '/home/example.com/public_html/results'; // 替换为你的实际路径
$auxfile = date('Ymd'); // 例如:20241201
$target = $base_dir . '/' . $auxfile;
if (!is_dir($target)) {
if (!mkdir($target, 0755, true)) { // 移除 @ 抑制符以便调试;0755 比 0777 更安全
$error = error_get_last();
error_log("Failed to create directory {$target}: " . ($error['message'] ?? 'Unknown error'));
exit(1);
}
}? 关键注意事项:
- 不要依赖 getcwd() 或相对路径:Cron 中 getcwd() 返回的是执行用户的 home 目录,与 Web 环境无关;
- 避免 @ 错误抑制符:它会掩盖真实错误(如“Permission denied”或“No such file or directory”),调试阶段务必移除;
- 检查 Cron 用户权限:确保运行 Cron 的用户(如 www-data、apache 或你的普通用户)对父目录(如 public_html/results/)具有写权限(chmod 755 或 775,视共享需求而定);
-
在 Cron 中显式指定 SHELL 和 PATH(推荐):
# 编辑 crontab 时添加环境声明 SHELL=/bin/bash PATH=/usr/local/bin:/usr/bin:/bin 0 2 * * * cd /home/example.com/public_html && /usr/bin/php /home/example.com/public_html/daily_mkdir.php >> /var/log/daily_mkdir.log 2>&1
- 验证路径存在性:mkdir($path, $mode, true) 的第三个参数 true 启用递归创建,但前提是父目录可写;若 results/ 本身不存在或不可写,仍会失败。
? 总结:Cron 下 PHP 的 mkdir() 失败,90% 是路径问题而非权限问题。坚持使用硬编码或配置化的绝对路径,配合日志记录与权限审计,即可稳定实现每日目录自动化创建。



















