WordPress 邮件配置:解决在 SourceForge 空间安装 WordPress 无法发送邮件的问题

插件已发布在 WordPress.org 官方网站,欢迎试用。

在 SourceForge 的 Project Web 或 User Web 中安装 WordPress 时,无法通过 WordPress 默认的方法发送邮件,但可以通过 SourceForge 提供的方法发送邮件(Project Web Email Configuration),示例代码如下:

<?php

include('Mail.php');

$recipients = array( 'someone@example.com' ); # Can be one or more emails

$headers = array (
  'From' => 'someone@example.com',
  'To' => join(', ', $recipients),
  'Subject' => 'Testing email from project web',
);

$body = "This was sent via php from project web!n";

$mail_object =& Mail::factory('smtp',
 array(
  'host' => 'prwebmail',
  'auth' => true,
  'username' => 'YOUR_PROJECT_NAME',
  'password' => 'PASSWORD', # As set on your project's config page
  #'debug' => true, # uncomment to enable debugging
));

$mail_object->send($recipients, $headers, $body);

要解决 SourceForge 空间下 WordPress 发送邮件的主要思路就是用上面代码替换掉 WordPress 发送邮件的原始代码。

方法一:修改源代码

分析源代码,发现 WordPress 使用 PHPMailer 来发送邮件,发送邮件的代码位于wp-includes/pluggable.php文件,函数为

function wp_mail( $to, $subject, $message, $headers = '', $attachments = array())

在该函数中找到代码

do_action_ref_array( 'phpmailer_init', array( &$phpmailer ) );

在后面添加 SourceForge 提供的邮件配置参数即可,如下:

do_action_ref_array( 'phpmailer_init', array( &$phpmailer ) );
//$phpmailer->FromName = 'WordPress';
$phpmailer->Host = 'prwebmail'; //host: prwebmail (or ssl://prwebmail)
//$phpmailer->Port = 25; //port: 25 (or 465 for ssl)
$phpmailer->Username = 'YOUR_PROJECT_NAME'; //user: YOUR_PROJECT_NAME
$phpmailer->Password = 'PASSWORD'; //password: THE_PASSWORD_YOU_CONFIGURED_FOR_YOUR_PROJECT, As set on your project's config page;
$phpmailer->From = 'someone@example.com'; //eg. yourname@users.sourceforge.net
$phpmailer->SMTPAuth = true;
$phpmailer->SMTPSecure = 'tls'; //tls or ssl
$phpmailer->IsSMTP();

注意修改 Username、Password、From等信息,参数含义参考 SourceForge Project Web Email Configuration

修改完 pluggable.php 后,通过 SSH 将文件上传到服务器上相应路径覆盖原文件(作为一个好习惯,应该在覆盖前备份原文件),修改 pluggable.php 文件的权限为 other 不可读(因为文件中有账号密码等敏感信息),MOD 值640。

chmod o-r pluggable.php

此时,WordPress 应该可以外发邮件了。可在登录页面使用找回密码功能进行测试。

方法二:使用插件

目前已经有一些插件可以解决 SourceForge 空间下 WordPress 发送邮件的问题,比如 Configure SMTP。

本站写了第一个 WordPress 插件,虽然功能没有 Configure SMTP 那么强大,但其专门为解决这个问题而设计,插件就一个文件,代码只有短短几行,足够简单高效。

该插件的原理就是将 SourceForge 提供的 Email 配置 HOOK 到 WordPress 的 wp_mail() 函数里,使得邮件功能在 SourceForge 空间下也可以正常工作。

WordPress 发送邮件的函数 wp_mail() 中调用了do_action_ref_array( ‘phpmailer_init’, array( &$phpmailer ) ) 函数,插件通过 add_action() 注册一个 phpmailer_init 函数,该函数将 SourceForge Email 配置传递给 phpmailer 对象,这样系统每次调用 wp_mail() 函数时都能使用 SourceForge 的Email 配置。

手动创建插件过程如下:

创建文件 sourceforge-email-config.php,内容如下:

<?php
/**
* @package sourceforge-email-config
* @version 1.0-RC1
*/
/*
Plugin Name: SourceForge Project Web Email Configuration
Plugin URI: http://opoo.org/sourceforge-wordpress-email-configuration/
Description: 在SourceForge的<a href="http://sourceforge.net/apps/trac/sourceforge/wiki/Project%20web">Project Web</a>或User Web中安装WordPress时,无法通过WordPress默认的方法发送邮件,但可以通过SourceForge提供的方法发送邮件(<a href="http://sourceforge.net/apps/trac/sourceforge/wiki/Project%20Web%20Email%20Configuration">Project Web Email Configuration</a>)。插件将SourceForge提供的Email配置HOOK到WordPress的wp_mail()函数里,使得邮件功能在SourceForge空间下也可以正常工作。<b>在启用插件前,需要手动修改插件源文件中有关SourceForge的配置。</b>
Author: Alex Lin
Version: 1.0-RC1
Author URI: http://opoo.org/about/
*/

//使用SourceForge的Email配置来初始化PHPMailer对象
function phpmailer_init_sourceforge($phpmailer) {
//$phpmailer->FromName = 'WordPress';
$phpmailer->Host = 'prwebmail'; //host: prwebmail (or ssl://prwebmail)
//$phpmailer->Port = 25; //port: 25 (or 465 for ssl)
$phpmailer->Username = 'YOUR_PROJECT_NAME'; //user: YOUR_PROJECT_NAME
$phpmailer->Password = 'PASSWORD'; //password: THE_PASSWORD_YOU_CONFIGURED_FOR_YOUR_PROJECT, As set on your project's config page;
$phpmailer->From = 'someone@example.com'; //eg. yourname@users.sourceforge.net
$phpmailer->SMTPAuth = true;
$phpmailer->SMTPSecure = 'tls'; //tls or ssl
$phpmailer->IsSMTP();
}

//参考wp_mail()函数中的代码: do_action_ref_array( 'phpmailer_init', array( &$phpmailer ) );
add_action( 'phpmailer_init', 'phpmailer_init_sourceforge');
?>

注意修改 Username、Password、From等信息,参数含义参考 SourceForge Project Web Email Configuration

将文件保存成 UTF-8 编码(最好使用 EditPlus 之类的编辑工具),然后上传到你的 SourceForge 下WordPress 的插件目录(wp-content/plugins),然后在插件管理里启用该插件即可(插件名称:SourceForge Project Web Email Configuration)。然后可使用找回密码功能进行测试。

该插件当前版本尚不支持在 WordPress 后台管理界面中配置 SourceForge Email 参数,而是将参数直接写在插件源文件里,这样减少了查询提高了效率。如果不知道如何修改源代码,请选用其它插件。(正式版本已经推出,带有配置界面,欢迎使用

总结一下:
如果担心过多的插件会影响 WordPress 的效率,可以选用方法一直接修改源代码;如果要保持WordPress 源代码不变又兼顾效率,可以选用方法二;如果要使用其它 SMTP 服务器,可以考虑类似Configure SMTP 的插件。

SourceForge Project Web Email Configuration(RC版)插件下载
(极简版,需要修改插件代码手动配置,适合高手,个人推荐使用)

SourceForge Project Web Email Configuration(正式版)插件下载
(正式版,带有简单后台配置界面,适合大众。从 WordPress.org 下载)

PS:

1. 要测试本插件是否运行,请在登录界面使用忘记密码找回密码功能进行测试,能收到邮件即表示插件正常工作。勿以是否收到评论回复邮件为判断标准,因为 WordPress 的本身或者您的主题可能不支持回复评论时发送邮件。

2. 要在旧版 SourceForge.net 设置 SMTP 密码,其步骤是:登录您的项目管理界面,在“Project Admin” -> “Features” -> “Manage” 中设置。

Configure your project’s email password.

  • Use the Project Admin / Features menu choice and choose “Manage” from the “Project Web” line.
  • Set the password you want to use in the provided text entry and press the “Set Passwords” button.

3. 要在新版SourceForge.net 设置 SMTP 密码,其步骤是:登录您的项目管理界面,点“Admin”按钮,打开“Tools”菜单,在待选工具“Click to install”里点击“Project Web Outgoing Email”,然后在下面已安装的工具里找到“PRWebEmail”,点击菜单“Admin Project Web Outgoing Email”,然后在出来的界面里填写“SMTP Password”。新版里已经明确把这个密码叫做“SMTP Password”了。

UPDATE:

插件 1.0.1 版本已经发布,可以在 WordPress.org 官网下载。这个版本可以使用SSL协议发送邮件了,之前的版本由于一个 BUG 导致 SSL 协议发送邮件失败。

WordPress 邮件配置:解决在 SourceForge 空间安装 WordPress 无法发送邮件的问题》上有 64 条评论

    1. Alex Lin 文章作者

      没有试过哦,听你这么说,我立马翻了一下Configure SMTP的源代码,发现也是HOOK了phpmailer_init函数,也是修改了phpmailer对象,原理应该差不多吧。

      回复
    1. Alex Lin 文章作者

      如果这些插件是调用WordPress的本身的函数wp_mail()发送备份邮件的话,理论上可行,等下班后我研究研究 :)

      回复
    1. Alex Lin 文章作者

      你在这里留言应该会有自动邮件吧,WordPress什么情况下发评论邮件我还不大清楚,试试看这条能收到不?

      回复
    2. Alex Lin 文章作者

      经过一番研究,发现WordPress的默认行为是能在他人评论时给管理员发送邮件的,而回复评论时通常是不发邮件的,如果需要在回复评论时也发送邮件,要么你选择的主题支持,要么你的插件支持(比如wp-thread-comment插件)。如果没有意外的,这次的回复你能收到回复评论邮件了。

      回复
    1. Alex Lin 文章作者

      SourceForge Project Web设置Project密码的地方在这里:打开SourceForge.net,右上角登录,在右上角选“Account”,打开“Projects” 菜单,找到你的项目,点击项目名称的链接进入项目管理,点击菜单“Project Admin”的“Features”,然后再表格中的“Project Web”那一行的最后有个“Manage”,进入就是设置项目密码的地方。

      回复
        1. Alex Lin 文章作者

          根据你截图的界面看,你进的好像是SourceForge的Developer Web(User Web)而不是Project Web,登录sourceforge.net后,打开地址https://sourceforge.net/develop ,在右边的“My Projects”那个块里非“Create a Project”的链接就是你的项目的链接,进去之后可以管理。其实还有种更直接的方式,直接打开你的SF项目地址,登录后就可以看到“Project Admin”菜单了,项目地址是https://sourceforge.net/projects/PROJECT_NAME/ ,比如我的JOQS开源项目的地址是 https://sourceforge.net/projects/joqs/
          如果有需要也有时间,将来我可能会写个图文教程。

          回复
  1. Mp

    已经弄好了,方法不如同你所说,我是要在admin下添加tool,“Project Web Outgoing Email”这个tool里设置密码,就好了!Anyway,感谢你的无私解答。但是sf服务器还是不能解决外链服务器这个问题吧?

    回复
    1. Alex Lin 文章作者

      可能每个人的项目管理界面都不同,你的有“Admin”菜单,我的没有;我的有“Project Admin”菜单,你没有。官方的文档里确实写着“Project Admin”,或许还有其它文档?不管怎样能解决问题就好。
      SourceForge Project Web后端不能外连,这是一个硬性限制,主要影响自动升级功能和反垃圾插件功能等,暂时无法解决。

      回复
        1. Alex Lin 文章作者

          应该是早期申请的是“Project Admin”吧,我的项目在2007年开通的,Mp是在2012年申请的。没想到操作是如此不同。

          回复
  2. Pingback 引用通告: Sourceforge的邮件函数啊啊啊 | Seasons In The Sun

  3. 鬼娃娃

    $phpmailer->Username = ‘YOUR_PROJECT_NAME’; //user: YOUR_PROJECT_NAME $phpmailer->Password = ‘PASSWORD’; //password: THE_PASSWORD_YOU_CONFIGURED_FOR_YOUR_PROJECT, As set on your project’s config page; $phpmailer->From = ‘someone@example.com’; //eg. yourname@users.sourceforge.net

    这三个是什么用户名+密码啊

    回复
    1. Alex Lin 文章作者

      请从WordPress.org下载这个插件的可配置版本吧,那个配置界面中对各个参数有详细的说明。
      简单说来项目名称就是你在sf注册的开源项目的名称,密码是你在文中所述的配置页设置的smtp密码,发送地址就是你在sf的用户名@users.sourceforge.net,这个邮箱地址是sf分给你的邮箱别名,实际指向你注册时所填的邮箱地址。
      电脑送修手机码字不便,有问题欢迎再留言。

      回复
  4. xhhjin

    当SF的项目名称是中文时,该方法会失效,找回密码时,显示的是“无法发送电子邮件。可能原因:您的主机禁用了 mail() 函数…”,应该是编码问题,但我网上找的几个方法试了都不行,不知道博主有什么方法吗?

    回复
    1. Alex Lin 文章作者

      SF的项目名称可以是中文吗?那访问地址岂不是http://中文.sourceforge.net/?这个我真没有试过。你可以试试我写的那个极简版本的插件,下载下来后自己修改里面的参数,保存时编码选择UTF-8,上传上去试试。

      最好是先对SF发邮件的功能进行测试下:使用文章开头提到的SF的官方代码编写一个PHP文件,修改相应的参数,收件人填写自己的邮箱,然后上传到你的project-web,调用一下,看看能不能收到邮件。

      回复
      1. xhhjin

        sorry,是我弄混了,在Project Admin界面下有Name和Unixname,其中的name是可以中文的(类似于昵称吧),Unixname是访问用的。我以为你的上面说的是name,实际上用的是Unixname。

        回复
  5. avoyoo

    博主你好,我有一个问题。
    很奇怪,我已经上载好了WP,并安装好,也绑定了域名,直接访问域名也可以访问博站。
    但是我点击博站的文章时是跳转到sourceforge.net/p=1这样的地址,而不是绑定域名的Xxxxx.tk/P=1这样的。
    请教,希望能够有时间指教下。谢谢。

    回复
  6. tonyho

    你好,还有个问题:
    在使用configure SMTP工具时:
    我直接使用了QQEmail,其中配置如下:
    SMTP host : smtp.qq.com
    SMTP port : 465
    Secure connection prefix : ssl
    Use SMTPAuth? : 选中
    SMTP username : ******@qq.com //QQ邮箱
    SMTP password : ****** //邮箱密码

    但是出现:
    SMTP Error: Could not connect to SMTP host.
    这个该如何解决呢?

    回复
  7. tonyho

    你好:
    现在使用Configure SMTP的Test功能可以收到邮件了,但是回复还是不可以收到邮件,我已经启用Configure SMTP插件了,是不是我还需要安装回复发送邮件的插件才可以完成回复后发邮件呢?

    回复
        1. Alex Lin 文章作者

          我的博客所使用的发邮件的插件是个特殊版本,除了sf邮件配置代码外,也添加了评论回复发邮件的代码。

          回复
  8. Pingback 引用通告: sf邮件自动回复 | 养猪大户

      1. Raa123

        启动插件了
        点击忘记密码时显示:
        无法发送电子邮件。
        可能原因:您的主机禁用了 mail() 函数…

        “已经弄好了,方法不如同你所说,我是要在admin下添加tool,“Project Web Outgoing Email”这个tool里设置密码,就好了!Anyway,感谢你的无私解答。但是sf服务器还是不能解决外链服务器这个问题吧?”

        $phpmailer->Password = ‘PASSWORD’; //password: THE_PASSWORD_YOU_CONFIGURED_FOR_YOUR_PROJECT, As set on your project’s config page;

        Password 我是按上面说的,用“Project Web Outgoing Email”这个tool里设置的密码

        求助。。。

        回复
        1. Alex Lin 文章作者

          sf项目管理有新旧两个版本,你这是新版的,我在文章的最后也有提及。

          sf空间的确不允许后台外联,会导致部分插件不可用。

          回复
        2. Raa123

          那我该怎么办呢?我也和你一样只是用@users.sf.net网站提供的邮箱啊,没有外联到其它邮箱啊,那你程序里$phpmailer->Password = ‘PASSWORD’; 的密码是指什么密码呢?

          回复
          1. Alex Lin 文章作者

            手机阅读不便,刚刚看错你的那段引用了。

            你是说你的外发邮件配置仍然没成功是吧? sf新旧两版设置外发邮件密码的方法在文章和评论里应该都能找到,你再仔细看看。

            另外,你的sf是新版还是旧版的?

    1. Alex Lin 文章作者

      貌似你曾经在评论里说通过手动添加代码已经解决了评论回复邮件的问题哦。

      我是在我的这个插件的源文件中定义了 function comment_mail_notify($comment_id) {...} 函数,然后添加了代码 add_action('comment_post', 'comment_mail_notify');,至于函数 comment_mail_notify 的内容,请参考wp-thread-comment插件的源代码。

      回复
    1. Alex Lin 文章作者

      SourceForge 一般不删空间吧。看看你的项目是不是升级为新版了,升级后可能需要重新设置外发邮件的密码。

      我正准备升级到新版,博客会不会受影响还不明。

      回复
        1. Alex Lin 文章作者

          我的项目已经升级了,发送邮件还是没有问题,看到你的回复的邮件才上来看回复的。所以你那边还是需要检查一下各个参数的配置,特别是外发邮件的密码。

          回复
  9. Kis

    我也是用SF空间建wordpress的,我用您的方法一、二也都成功了。可我本想那个自动备份的插件就不信了:
    1.用了方法一成功后,备份文件到邮箱却提示“发现以下错误: Only variables should be passed by reference”
    2.接着,方法二也成功了,可备份邮箱时,却提示“发现以下错误: fsockopen() [function.fsockopen]: unable to connect to ssl://smtp.sourceforge.net:25 (No route to host)”
    求解啊,我用WordPress Database Backup插件的,邮箱也是用SF官方给的,就备份出问题,其他回复邮件功能一律成功。

    回复
    1. Alex Lin 文章作者

      最近我在使用SSL协议发送SF邮件时,发现系统会在sf的邮件服务器 prwebmail 前自动加上 ssl:// 字符串,而我的插件在选择了SSL协议时也会在 prwebmail 前面加 ssl:// 字符串,这样就导致了邮件服务器地址不正确,就会产生你所说的错误,但在非SSL协议下是没有问题的。
      我会尽快修正这个bug,谢谢关注啊。

      回复

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>