WordPress命令行下wp_mail()无法发送邮件问题求助
问题根源
这个问题我之前帮不少开发者排查过,核心原因很清晰——命令行环境下WordPress没法自动获取站点域名。当你通过浏览器访问时,WordPress能从服务器的HTTP_HOST等环境变量里拿到站点域名,默认发件人会自动补全成wordpress@yourdomain.com;但命令行执行脚本时没有这些HTTP相关的环境变量,WordPress识别不出域名,就生成了不完整的wordpress@地址,直接触发了wp_mail_failed错误。
解决方案
1. 调用wp_mail时显式指定发件人
最直接的方式是在调用wp_mail()时,手动传入完整的发件人信息,不依赖默认值。通过$headers参数就能实现:
// 基础邮件参数 $to = 'recipient@example.com'; $subject = '定时任务通知邮件'; $message = '这是来自命令行定时任务的测试内容'; // 自定义发件人头部(替换成你的实际域名邮箱) $headers = array( 'From: 你的站点名称 <wordpress@yourdomain.com>', 'Content-Type: text/html; charset=UTF-8' ); // 执行发送 wp_mail($to, $subject, $message, $headers);
2. 用过滤器全局修改默认发件人
如果你的插件多处用到wp_mail(),可以添加全局过滤器,强制统一发件人地址,避免重复写代码:
// 替换默认发件人邮箱 add_filter('wp_mail_from', 'custom_wp_mail_from'); function custom_wp_mail_from($original_email) { return 'wordpress@yourdomain.com'; // 替换成你的实际邮箱 } // 可选:替换默认发件人名称 add_filter('wp_mail_from_name', 'custom_wp_mail_from_name'); function custom_wp_mail_from_name($original_name) { return '你的站点名称'; }
把这段代码放在插件主文件或者主题的functions.php里,确保在调用wp_mail()之前加载即可。
3. 确保定时任务脚本正确加载WordPress环境
如果你的定时任务是单独的PHP文件,必须先正确加载WordPress核心环境,否则不仅发件人会出问题,大部分WP函数都没法正常工作。在脚本开头添加:
// 禁用主题加载(可选,根据需求调整) define('WP_USE_THEMES', false); // 替换成你的WordPress根目录绝对路径 require('/var/www/html/wp-load.php');
注意:命令行环境下相对路径容易出错,建议直接写服务器上的绝对路径,比如/var/www/html/wp-load.php,可以用getcwd()命令查看当前工作目录辅助确认。
4. (可选)在定时任务中设置环境变量
如果不想修改代码,也可以在设置crontab定时任务时,手动传入HTTP_HOST环境变量,让WordPress能识别域名:
* * * * * HTTP_HOST=yourdomain.com php /path/to/your/script.php
这样WordPress会读取这个环境变量,自动补全默认发件人的域名部分。
测试验证
设置完成后,直接在命令行执行脚本测试:
php /path/to/your/script.php
如果没有报错,再检查收件箱是否收到邮件即可。
内容的提问来源于stack exchange,提问作者Akhilesh

