假设我们有空白的WP站点,并且我们想以编程方式在插件或主题中设置SMTP设置。不更改核心文件的最简单方法是什么?

#1 楼

首先,如果我们看一下wp_mail函数的实现,我们将看到该函数使用PHPMailer类发送电子邮件。我们还可以注意到有一个硬编码函数调用$phpmailer->IsMail();,该函数设置为使用PHP的mail()函数。这意味着我们不能使用SMTP设置。我们需要调用isSMTP类的PHPMailer函数。而且我们还需要设置SMTP设置。

要实现此目的,我们需要访问$phpmailer变量。在这里,我们来进行phpmailer_init操作,该操作在发送电子邮件之前被调用。因此,我们可以通过编写动作处理程序来完成所需的操作:

add_action( 'phpmailer_init', 'wpse8170_phpmailer_init' );
function wpse8170_phpmailer_init( PHPMailer $phpmailer ) {
    $phpmailer->Host = 'your.smtp.server.here';
    $phpmailer->Port = 25; // could be different
    $phpmailer->Username = 'your_username@example.com'; // if required
    $phpmailer->Password = 'yourpassword'; // if required
    $phpmailer->SMTPAuth = true; // if required
    // $phpmailer->SMTPSecure = 'ssl'; // enable if required, 'tls' is another possible value

    $phpmailer->IsSMTP();
}


就这么简单。

评论


好东西,尤金,谢谢!我猜这10行代码可以替代整个SMTP插件...(?)

–brasofilo
2012-12-13 11:59

@brasofilo thx!我认为它不能替代SMTP插件,因为该插件允许您在管理面板上配置设置。此代码段只是关于“如何以编程方式更改电子邮件设置”而不破坏核心文件或不重写wp_mail函数的最佳实践。

– Eugene Manuilov
2012年12月13日在12:40

此代码应放在哪里?我想让所有主题都使用相同的SMTP服务器。

– Anjan
2014年1月10日14:43

非常奇怪的WP并没有使它变得更容易,因为您会认为修改它是很常见的。

–卡森·莱因克(Carson Reinke)
15年4月30日在13:14

它对我有用,@ JackNicholson,您也应该在末端检查它。

– Eugene Manuilov
2015年11月9日14:41

#2 楼

@EugeneManuilov答案的补充。

SMTP设置

默认情况下,只能在已附加do_action_ref_array()的回调期间设置-因为@EugeneManuilov已回答-设置。源/核心。

<?php
defined( 'ABSPATH' ) OR exit;
/**
 * Plugin Name: (WCM) PHPMailer SMTP Settings
 * Description: Enables SMTP servers, SSL/TSL authentication and SMTP settings.
 */

add_action( 'phpmailer_init', 'phpmailerSMTP' );
function phpmailerSMTP( $phpmailer )
{
    # $phpmailer->IsSMTP();
    # $phpmailer->SMTPAuth   = true;  // Authentication
    # $phpmailer->Host       = '';
    # $phpmailer->Username   = '';
    # $phpmailer->Password   = '';
    # $phpmailer->SMTPSecure = 'ssl'; // Enable if required - 'tls' is another possible value
    # $phpmailer->Port       = 26;    // SMTP Port - 26 is for GMail
}


SMTP异常

默认情况下,WordPress不会提供任何调试输出。相反,如果发生错误,它将仅返回FALSE。以下是解决此问题的小插件:

<?php
defined( 'ABSPATH' ) OR exit;
/**
 * Plugin Name: (WCM) PHPMailer Exceptions & SMTP
 * Description: WordPress by default returns <code>FALSE</code> instead of an <code>Exception</code>. This plugin fixes that.
 */

add_action( 'phpmailer_init', 'WCMphpmailerException' );
function WCMphpmailerException( $phpmailer )
{
    if ( ! defined( 'WP_DEBUG' ) OR ! WP_DEBUG )
    {
        $phpmailer->SMTPDebug = 0;
        $phpmailer->debug = 0;
        return;
    }
    if ( ! current_user_can( 'manage_options' ) )
        return;

    // Enable SMTP
    # $phpmailer->IsSMTP();
    $phpmailer->SMTPDebug = 2;
    $phpmailer->debug     = 1;

    // Use `var_dump( $data )` to inspect stuff at the latest point and see
    // if something got changed in core. You should consider dumping it during the
    // `wp_mail` filter as well, so you get the original state for comparison.
    $data = apply_filters(
        'wp_mail',
        compact( 'to', 'subject', 'message', 'headers', 'attachments' )
    );

    current_user_can( 'manage_options' )
        AND print htmlspecialchars( var_export( $phpmailer, true ) );

    $error = null;
    try
    {
        $sent = $phpmailer->Send();
        ! $sent AND $error = new WP_Error( 'phpmailerError', $sent->ErrorInfo );
    }
    catch ( phpmailerException $e )
    {
        $error = new WP_Error( 'phpmailerException', $e->errorMessage() );
    }
    catch ( Exception $e )
    {
        $error = new WP_Error( 'defaultException', $e->getMessage() );
    }

    if ( is_wp_error( $error ) )
        return printf(
            "%s: %s",
            $error->get_error_code(),
            $error->get_error_message()
        );
}


存储库

这些插件都可以在GitHub的Gist中使用,因此请考虑将这些插件检出从那里获取任何更新。

#3 楼

这篇文章的其他答案虽然提供了可行的解决方案,但并未解决将SMTP凭据存储在插件文件或functions.php中的安全性问题。在某些情况下可能还可以,但是最佳实践将要求以更安全的方式存储此信息。在保护您的凭据方面,确实没有充分的理由不遵循最佳实践。

有人建议您将其保存到数据库中作为一种选择,但是根据数量的不同,也会出现相同的安全问题。网站拥有的管理用户的数量以及这些用户是否应该能够查看这些登录凭据。这也是不为此使用插件的原因。
做到这一点的最佳方法是在wp-config.php文件中为phpmailer info定义常量。实际上,这已作为邮件组件中的功能进行了讨论,但目前尚未被接受为实际的增强功能。但是您可以自己添加以下内容到wp-config.php中进行操作:通过使用定义的常数。因此,您可以在插件文件或functions.php中使用它们。 (特定于OP,请使用插件文件。)

/**
 * Set the following constants in wp-config.php
 * These should be added somewhere BEFORE the
 * constant ABSPATH is defined.
 */
define( 'SMTP_USER',   'user@example.com' );    // Username to use for SMTP authentication
define( 'SMTP_PASS',   'smtp password' );       // Password to use for SMTP authentication
define( 'SMTP_HOST',   'smtp.example.com' );    // The hostname of the mail server
define( 'SMTP_FROM',   'website@example.com' ); // SMTP From email address
define( 'SMTP_NAME',   'e.g Website Name' );    // SMTP From name
define( 'SMTP_PORT',   '25' );                  // SMTP port number - likely to be 25, 465 or 587
define( 'SMTP_SECURE', 'tls' );                 // Encryption system to use - ssl or tls
define( 'SMTP_AUTH',    true );                 // Use SMTP authentication (true|false)
define( 'SMTP_DEBUG',   0 );                    // for debugging purposes only set to 1 or 2


这篇文章对此有更多详细说明,github上的要点在这里。

评论


一个非常好的解决方案!

– Phill Healey
17年9月8日在18:14

小补充:不用说,不要在版本控制中存储凭据。请改用gitignored .env文件。但是没有人把任何敏感的东西放到wp-config.php中,无论如何都在使用版本控制…

– jsphpl
18年8月29日在15:32