
本文详解如何通过 launchd(配合 .plist 配置文件)在 macos 上精准实现每 60 秒自动运行一个 php 脚本,替代传统 cron,兼顾稳定性、用户会话感知与系统级管理能力。
本文详解如何通过 launchd(配合 .plist 配置文件)在 macos 上精准实现每 60 秒自动运行一个 php 脚本,替代传统 cron,兼顾稳定性、用户会话感知与系统级管理能力。
在 macOS 中,launchd 是官方推荐的守护进程管理机制,比 cron 更可靠、更安全,尤其适合需要与用户登录会话绑定的定时任务(如本地开发环境中的轮询、缓存刷新或轻量级队列处理)。要让一个 PHP 脚本每分钟执行一次,关键在于编写符合规范的 LaunchAgent plist 文件,并正确加载与调试。
✅ 步骤一:创建标准 LaunchAgent plist 文件
将以下内容保存为 ~/Library/LaunchAgents/com.yourname.php-minutely.plist(请将 yourname 替换为你的用户名或项目标识,确保命名符合反向域名格式):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.yourname.php-minutely</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/php</string>
<string>/Users/yourname/projects/myapp/scripts/sync.php</string>
</array>
<key>WorkingDirectory</key>
<string>/Users/yourname/projects/myapp</string>
<key>StartInterval</key>
<integer>60</integer>
<key>RunAtLoad</key>
<true/>
<!-- 可选:仅调试时启用,上线前务必注释 -->
<!--
<key>StandardOutPath</key>
<string>/tmp/php-minutely.log</string>
<key>StandardErrorPath</key>
<string>/tmp/php-minutely.err</string>
-->
</dict>
</plist>⚠️ 重要说明:
- ProgramArguments 中必须使用 绝对路径:/usr/bin/php(macOS 自带)或 which php 输出的实际路径(如 /opt/homebrew/bin/php);PHP 脚本路径也需绝对化。
- WorkingDirectory 应设为脚本依赖的根目录(例如含 vendor/ 或配置文件),避免因工作路径错误导致 require 失败或相对路径解析异常。
- StartInterval 60 表示固定间隔执行(从上一次执行结束开始计时),非“整点触发”。若需严格按系统时间对齐(如每分钟第 0 秒启动),应改用 StartCalendarInterval(但本场景不推荐,因其复杂度高且易受延迟影响)。
✅ 步骤二:设置权限并加载服务
执行以下命令确保 plist 文件权限合规(644 是 launchd 强制要求):
立即学习“PHP免费学习笔记(深入)”;
chmod 644 ~/Library/LaunchAgents/com.yourname.php-minutely.plist
验证权限是否与其他 LaunchAgent 一致:
ls -l ~/Library/LaunchAgents/com.yourname.php-minutely.plist # 应输出类似:-rw-r--r-- 1 yourname staff 523 Jan 15 10:30 com.yourname.php-minutely.plist
加载并启用任务:
launchctl load ~/Library/LaunchAgents/com.yourname.php-minutely.plist
? 提示:load 后任务即生效(RunAtLoad 为 true 会立即运行一次)。如需手动触发测试,运行:
launchctl start com.yourname.php-minutely
✅ 步骤三:调试与维护要点
- 日志策略:文中注释掉的 StandardOutPath / StandardErrorPath 仅限调试阶段临时启用。持续写入会导致日志文件无节制增长,严重时耗尽磁盘或拖慢系统。生产环境请移除或重定向至受控日志轮转方案(如配合 logrotate 或自定义日志清理脚本)。
- PHP 环境一致性:launchd 进程不继承 shell 的 PATH 或 .zshrc 环境变量。务必在 ProgramArguments 中显式指定完整 PHP 路径,并在脚本内使用绝对路径加载依赖(或通过 putenv() 设置必要环境变量)。
-
状态检查:随时查看任务状态:
launchctl list | grep yourname # 或更详细信息 launchctl print gui/$(id -u)/com.yourname.php-minutely
-
卸载与更新:修改 plist 后需先卸载再重载:
launchctl unload ~/Library/LaunchAgents/com.yourname.php-minutely.plist # 编辑文件后... launchctl load ~/Library/LaunchAgents/com.yourname.php-minutely.plist
? 总结
使用 launchd 实现分钟级 PHP 定时任务,本质是将脚本声明为受系统管理的用户级服务。其优势在于:无需守护进程常驻、天然支持用户登录/登出生命周期、权限隔离明确、且与 macOS 生态深度集成。只要严格遵循 plist 规范、路径绝对化、日志审慎启用,即可构建稳定可靠的自动化流程——这正是现代 macOS 开发运维的最佳实践之一。



















