Come impostare SMTP programmaticamente
Innanzitutto, se diamo un'occhiata all'implementazione della funzione wp_mail
, vedremo che questa utilizza la classe PHPMailer
per inviare email. Inoltre possiamo notare che c'è una chiamata di funzione hardcoded $phpmailer->IsMail();
, che imposta l'uso della funzione PHP mail()
. Ciò significa che non possiamo utilizzare le impostazioni SMTP con essa. Dobbiamo invece chiamare la funzione isSMTP
della classe PHPMailer
. Inoltre, dobbiamo anche impostare le nostre configurazioni SMTP.
Per ottenere questo risultato, abbiamo bisogno di accedere alla variabile $phpmailer
. Ed è qui che entra in gioco l'azione phpmailer_init
, che viene chiamata prima dell'invio di un'email. Quindi possiamo fare ciò di cui abbiamo bisogno scrivendo il nostro gestore di azione:
add_action( 'phpmailer_init', 'wpse8170_phpmailer_init' );
function wpse8170_phpmailer_init( PHPMailer $phpmailer ) {
$phpmailer->Host = 'il.tuo.server.smtp.qui';
$phpmailer->Port = 25; // potrebbe essere diverso
$phpmailer->Username = 'tuo_username@example.com'; // se richiesto
$phpmailer->Password = 'tuapassword'; // se richiesto
$phpmailer->SMTPAuth = true; // se richiesto
// $phpmailer->SMTPSecure = 'ssl'; // abilita se richiesto, 'tls' è un altro valore possibile
$phpmailer->IsSMTP();
}
E questo è tutto.

Ottimo lavoro, Eugene, grazie! Immagino che queste 10 righe di codice possano sostituire un intero plugin SMTP...(?)

@brasofilo grazie! Penso che non possa sostituire un plugin SMTP, perché il plugin ti permette di configurare le impostazioni dal pannello di amministrazione. Questo snippet è solo una best practice su "come modificare le impostazioni email programmaticamente" senza modificare i file core o senza riscrivere la funzione wp_mail
.

Forse un link al core? Ho appena scoperto che dobbiamo usare questo per SSL: $phpmailer->SMTPSecure = 'ssl';
, oppure 'tls'
se è il caso. ::: Ancora una volta, fantastico lavoro!

@brasofilo sì, sono d'accordo. Sentiti libero di modificare la risposta se vuoi. Grazie per l'aiuto.

Dove dovrebbe essere posizionato questo codice? Voglio che tutti i miei temi utilizzino gli stessi server SMTP.

@Anjan crea il tuo plugin personalizzato.

Molto strano che WordPress non renda più semplice questa modifica, considerando che sembrerebbe un'operazione piuttosto comune.

funziona per me, @JackNicholson dovresti verificarlo anche dal tuo lato.

Ho usato questo codice ma WordPress invia tramite php mail(), come forzare WordPress a inviare solo tramite SMTP? Quando uso wp_mail("hossein@hashemiui.com", "test", "test"); non lo invia tramite SMTP

Aggiunta alla risposta di @EugeneManuilov.
Impostazioni SMTP
Di default queste possono essere impostate - come già risposto da @EugeneManuilov - solo tramite un callback collegato a un'azione do_action_ref_array()
. Source/core.
<?php
defined( 'ABSPATH' ) OR exit;
/**
* Plugin Name: (WCM) PHPMailer SMTP Settings
* Description: Abilita server SMTP, autenticazione SSL/TLS e impostazioni SMTP.
*/
add_action( 'phpmailer_init', 'phpmailerSMTP' );
function phpmailerSMTP( $phpmailer )
{
# $phpmailer->IsSMTP();
# $phpmailer->SMTPAuth = true; // Autenticazione
# $phpmailer->Host = '';
# $phpmailer->Username = '';
# $phpmailer->Password = '';
# $phpmailer->SMTPSecure = 'ssl'; // Abilita se richiesto - 'tls' è un altro valore possibile
# $phpmailer->Port = 26; // Porta SMTP - 26 è per GMail
}
Eccezioni SMTP
Di default WordPress non fornisce alcun output di debug. Restituisce semplicemente FALSE
se si verifica un errore. Ecco un piccolo plugin per risolvere questo problema:
<?php
defined( 'ABSPATH' ) OR exit;
/**
* Plugin Name: (WCM) PHPMailer Exceptions & SMTP
* Description: WordPress di default restituisce <code>FALSE</code> invece di un'<code>Exception</code>. Questo plugin risolve il problema.
*/
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;
// Abilita SMTP
# $phpmailer->IsSMTP();
$phpmailer->SMTPDebug = 2;
$phpmailer->debug = 1;
// Usa `var_dump( $data )` per ispezionare i dati all'ultimo momento e vedere
// se qualcosa è stato modificato nel core. Potresti considerare di fare il dump
// anche durante il filtro `wp_mail`, così avrai lo stato originale per il confronto.
$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()
);
}
Repository
Entrambi i plugin sono disponibili in questo Gist su GitHub, quindi considera di scaricarli da lì per ottenere eventuali aggiornamenti.

Le altre risposte a questo post, pur fornendo una soluzione funzionante, non affrontano il problema della sicurezza relativo alla memorizzazione delle credenziali SMTP in un file di plugin o in functions.php. In alcuni casi potrebbe essere accettabile, ma le migliori pratiche suggeriscono di archiviare queste informazioni in modo più sicuro. Non c'è davvero una buona ragione per non seguire le migliori pratiche quando si tratta di proteggere le proprie credenziali.
Alcuni potrebbero suggerire di salvarle nel database come opzione, ma ciò presenta gli stessi problemi di sicurezza a seconda del numero di utenti amministrativi del sito e se questi utenti dovrebbero essere in grado di vedere queste credenziali di accesso. Questo è anche il motivo per cui non utilizzare un plugin per questo scopo.
Il modo migliore per farlo è definire delle costanti per le informazioni del phpmailer nel file wp-config.php. Questo è stato effettivamente discusso come una funzionalità nel componente Mail, ma non è stato ancora accettato come un effettivo miglioramento. Tuttavia, puoi farlo tu stesso aggiungendo quanto segue a wp-config.php:
/**
* Imposta le seguenti costanti in wp-config.php
* Queste dovrebbero essere aggiunte da qualche parte PRIMA della
* definizione della costante ABSPATH.
*/
define( 'SMTP_USER', 'user@example.com' ); // Username da usare per l'autenticazione SMTP
define( 'SMTP_PASS', 'smtp password' ); // Password da usare per l'autenticazione SMTP
define( 'SMTP_HOST', 'smtp.example.com' ); // Il nome host del server di posta
define( 'SMTP_FROM', 'website@example.com' ); // Indirizzo email SMTP From
define( 'SMTP_NAME', 'e.g Nome Sito Web' ); // Nome SMTP From
define( 'SMTP_PORT', '25' ); // Numero di porta SMTP - probabilmente 25, 465 o 587
define( 'SMTP_SECURE', 'tls' ); // Sistema di crittografia da usare - ssl o tls
define( 'SMTP_AUTH', true ); // Usare l'autenticazione SMTP (true|false)
define( 'SMTP_DEBUG', 0 ); // Solo per debug, impostare a 1 o 2
Una volta definite queste costanti in wp-config.php, possono essere utilizzate ovunque tramite la costante definita. Quindi potresti usarle in un file di plugin o nel tuo functions.php. (Specifico per l'OP, usa un file di plugin.)
/**
* Questa funzione collegherà wp_mail al tuo server SMTP autenticato.
* I valori sono costanti impostate in wp-config.php
*/
add_action( 'phpmailer_init', 'send_smtp_email' );
function send_smtp_email( $phpmailer ) {
$phpmailer->isSMTP();
$phpmailer->Host = SMTP_HOST;
$phpmailer->SMTPAuth = SMTP_AUTH;
$phpmailer->Port = SMTP_PORT;
$phpmailer->Username = SMTP_USER;
$phpmailer->Password = SMTP_PASS;
$phpmailer->SMTPSecure = SMTP_SECURE;
$phpmailer->From = SMTP_FROM;
$phpmailer->FromName = SMTP_NAME;
}
C'è qualche dettaglio in più su questo in questo post e un gist su GitHub qui.
