إذا كانت نماذجك تُرسل رسالة "تم إرسال الرسالة" ولكن لا يصل شيء إلى صندوق الوارد، فغالبًا ما تواجه مشكلة WordPress من يقوم بالشحن عبر mail() - ومزود خدمة استضافة يقوم بتصفية الرسائل أو تحديد معدل نقلها أو توقيعها بشكل غير صحيح. WordPress 6.9.4، الطريقة الأكثر موثوقية لا تزال SMTP ... ويمكنك القيام بذلك بشكل نظيف بدون مكون إضافي، باستخدام مكون إضافي MU بسيط وقابل للإصدار والتدقيق.
ما سنقوم ببنائه
ستقوم بإعداد تهيئة SMTP كاملة لإرسال رسائل البريد الإلكتروني عبر ووردبريس، دون تثبيت أي إضافات. والنتيجة النهائية:
- يرسل ووردبريس عبر خادم SMTP الخاص بك (أو خادم وسيط مثل Mailgun/SendGrid/SMTP pro) بدلاً من
mail(). - هويات المرسل (من) متسقة ولا تتم إعادة كتابتها بواسطة قالب أو أداة إنشاء.
- لديك سجلات تشخيصية قابلة للاستخدام (دون الكشف عن كلمة المرور) مرر SMTP).
- لديك صفحة إدارة باسم "اختبار SMTP" للتحقق من صحة البيانات في غضون 30 ثانية بعد كل تغيير.
وهو مخصص لمواقع العرض، والمدونات، و WooCommerce، والمواقع التي تحتوي على نماذج (Contact Form 7، و Gravity Forms، و WPForms...)، والبيئات التي تريد فيها تجنب تأثير "إضافة مكون إضافي" (أو مكونات إضافية صغيرة تتعطل مع أدنى تحديث).
في النهاية، ستعرف أين تُرفق الكود (الخطاف). phpmailer_init)، وكيفية تأمين الأسرار، وكيفية تشخيص أخطاء SMTP الحقيقية (TLS، والمصادقة، والمنافذ، وDNS).
ملخص سريع
- نقوم بتهيئة PHPMailer عبر الخطاف
phpmailer_init(WordPress 6.9.4) للتبديل إلى SMTP. - وضعنا الكود في إضافة MU (
wp-content/mu-plugins/) بحيث يكون مشحونًا دائمًا. - تُخزن الأسرار في
wp-config.php(أو متغيرات البيئة)، لا يتم تضمينها بشكل ثابت في مستودع Git. - نحن نجبر من / من الاسم ونحن نحمي من عمليات إعادة الكتابة الشائعة.
- نضيف سجلات وصفحة اختبار إدارية مع رمز عشوائي للتحقق من الصحة واستكشاف الأخطاء وإصلاحها. برغي.
متى يستخدم هذا الحل
- أنت تريد إعداد SMTP قابل للتدوين (ملف PHP واضح) و قابل للإصدار (جيت)، بدون واجهة إضافية.
- أنت تدير بيئات متعددة (محلية / تجريبية / إنتاجية) وتريد التبديل عبر متغيرات البيئة.
- هل سبق لك أن واجهت تعارضات بين إضافات "SMTP" وإضافات النماذج (لقد رأيت في كثير من الأحيان تكوينين لـ SMTP يتعارضان، مع مهلات عشوائية).
- تريد التحكم في التفاصيل (TLS/SSL، المنافذ، المهلات، التصحيح) دون الاعتماد على مكون إضافي يغير واجهة المستخدم.
متى لا يجب استخدام هذا الحل
- ليس لديك حق الوصول إلى الملفات (FTP/SFTP/SSH) أو لا يمكنك تعديلها.
wp-config.php. - تتطلب مؤسستك التدوير التلقائي للأسرار عبر مدير (مدير الخزائن/الأسرار) وليس لديك مسار النشر المناسب.
- إذا كنت بحاجة إلى وظائف "تسويق" متقدمة (التتبع، والقوالب، وخطافات الويب، وسجلات واجهة المستخدم، وإعادة المحاولات): فسيكون المكون الإضافي أو مجموعة تطوير البرامج من الموفر أكثر ملاءمة.
- لا يمكنك توفير الصيانة: يمكن أن يؤدي نسيان جزء من بروتوكول SMTP إلى تعطيل الإرسال بعد تغيير كلمة المرور، ولا أحد ينظر إلى السجلات.
قبل البدء (المتطلبات الأساسية)
الإصدارات والبيئة
- ووردبريس: 6.9.4 (أبريل 2026) أو أحدث.
- بي أتش بي : 8.1+ (يفضل استخدام الإصدار 8.2/8.3 إذا كان مزود خدمة الاستضافة الخاص بك يسمح بذلك).
- الوصول: القدرة على إنشاء ملف في
wp-content/mu-plugins/ولتعديلwp-config.php.
النسخ الاحتياطي والاختبار
- قم بعمل نسخة احتياطية (للملفات وقاعدة البيانات) واختبرها أولاً على بيئة تجريبية إن أمكن. قد يتسبب خادم SMTP معطل في منع إرسال رسائل البريد الإلكتروني الهامة (إعادة تعيين كلمة المرور، طلبات WooCommerce).
- قم بإعداد حساب بريد إلكتروني تجريبي خارجي (Gmail، Outlook، Proton) وعنوان على نطاقك.
الأمن (يجب أخذه على محمل الجد)
- لا تضع أبدا كلمة مرور SMTP مُضمنة في قالب، أو إضافة عادية، أو جزء من التعليمات البرمجية تم نسخه ولصقه في لوحة التحكم. ينتهي بها المطاف في ملفات التصدير، أو النسخ الاحتياطية، أو لقطات الشاشة.
- استخدام حساب SMTP مخصص (أو مفتاح واجهة برمجة تطبيقات SMTP) مع الحد الأدنى من الصلاحيات.
- إذا قمت بتمكين تصحيح أخطاء SMTP، فافعل ذلك مؤقتًا وقم بتسجيل الدخول على جانب الخادم، وليس على الشاشة.
مراجع رسمية مفيدة (ستصادفها مرة أخرى)
- هوك phpmailer_init (ووردبريس)
- وظيفة wp_mail() (ووردبريس)
- إضافات MU (ووردبريس)
- نسخة احتياطية من منصة جيت هاب الخاصة بنظام ووردبريس الأساسي (للتحقق من السلوك)
- امتداد OpenSSL (PHP)
الخطوة 1: اختر مزود خدمة SMTP الخاص بك واسترجع الإعدادات الصحيحة
يصبح الكود عديم الفائدة إذا كانت إعدادات SMTP غير صحيحة. الأخطاء التي أراها في أغلب الأحيان هي:
- عدم اتساق المنفذ/TLS (على سبيل المثال، المنفذ 587 ولكن "SSL" بدلاً من "TLS").
- المعرّف = البريد الإلكتروني الكامل مقابل تسجيل الدخول المختصر (يعتمد ذلك على مزود الخدمة).
- اسم مضيف غير صحيح (على سبيل المثال،
smtp.mail.domain.tldبدلا منsmtp.domain.tld).
المعايير النموذجية
| المعلمة | القيمة النموذجية | ملاحظة |
|---|---|---|
| مضيف | smtp.votre-fournisseur.tld |
يجب حلها في نظام أسماء النطاقات (DNS) من الخادم |
| ميناء | 587 | STARTTLS (الأكثر شيوعًا) |
| التشفير | tls |
STARTTLS على الرقم 587 |
| ميناء (بديل) | 465 | SMTPS (TLS الضمني) |
| المصادقة | نعم | Souvent requis |
| اسم المستخدم | حساب/مفتاح SMTP | أحيانًا مفتاح API |
| كلمة المرور | كلمة المرور / السر | يُخزن خارج المستودع |
فحص سريع من جانب الخادم (اختياري ولكنه مفيد)
إذا كان لديك وصول SSH، فقم باختبار اتصال الشبكة (هذا يتجنب كتابة التعليمات البرمجية فقط لتكتشف لاحقًا أن المنفذ محظور من قبل مزود الاستضافة).
# Test DNS
getent hosts smtp.votre-fournisseur.tld
# Test TCP (587)
nc -vz smtp.votre-fournisseur.tld 587
# Test TLS (STARTTLS sur 587)
openssl s_client -starttls smtp -connect smtp.votre-fournisseur.tld:587 -servername smtp.votre-fournisseur.tld
النتيجة المتوقعة: اتصال ناجح وعرض الشهادة بدون أخطاء جوهرية. nc إذا فشلت هذه العملية، فقد يكون مزود خدمة الاستضافة الخاص بك يحظر حركة مرور SMTP الصادرة.
الخطوة 2: إنشاء إضافة SMTP MU نظيفة وقابلة للتحديث وخالية من التبعيات
يتم تحميل إضافة MU تلقائيًا، دون الحاجة إلى تفعيلها في لوحة التحكم. وهذا مثالي لإعدادات "البنية التحتية" مثل SMTP. كما أنها طريقة جيدة لتجنب الخطأ الشائع المتمثل في لصق الكود في functions.php ثم قم بتغيير المظهر وستفقد كل شيء.
أين يتم إنشاء الملف
- فتح
wp-content/. - إذا كان الملف
mu-pluginsإذا لم يكن موجوداً، فأنشئه:wp-content/mu-plugins/. - أنشئ الملف:
wp-content/mu-plugins/bpcab-smtp.php.
ألصق هذا الهيكل العظمي (لا توجد أسرار في الوقت الحالي)
<?php
/**
* Plugin Name: BPCAB SMTP (MU)
* Description: Configuration SMTP sans plugin via PHPMailer pour WordPress 6.9.4+.
* Author: Votre Nom
* Version: 1.0.0
*
* Ce fichier est un MU-plugin : placez-le dans wp-content/mu-plugins/.
*/
defined('ABSPATH') || exit;
/**
* Retourne une valeur de configuration SMTP depuis :
* 1) une constante (wp-config.php)
* 2) une variable d'environnement
*
* Note : on ne met PAS de valeurs par défaut sensibles ici.
*/
function bpcab_smtp_get_config(string $key, $default = null) {
$const = 'BPCAB_SMTP_' . strtoupper($key);
if (defined($const)) {
return constant($const);
}
$env = getenv($const);
if ($env !== false && $env !== '') {
return $env;
}
return $default;
}
/**
* Active/désactive SMTP. Pratique pour un rollback rapide.
*/
function bpcab_smtp_is_enabled(): bool {
return (bool) bpcab_smtp_get_config('enabled', false);
}
النتيجة المتوقعة بعد هذه الخطوة: لم يطرأ أي تغيير حتى الآن، ولكن من المفترض ألا يتعطل موقعك. إذا ظهرت لك شاشة بيضاء، فربما يكون لديك:
- تم نسخ الملف إلى موقع خاطئ (على سبيل المثال:
wp-content/pluginsبدلا منmu-plugins)، أو - يُدخل خطأً في بناء الجملة (أقواس/فاصلة منقوطة).
الخطوة 3: إدخال بيانات الاعتماد بشكل آمن (ملف wp-config.php ومتغيرات البيئة)
الفخ الكلاسيكي: وضع $password = 'monmdp'; في إضافة MU، عند تنفيذ أمر commit، ينتهي الأمر بكلمة المرور في المستودع، أو في ملف مضغوط مُرسل إلى العميل، أو في نسخة احتياطية مشتركة. لقد رأيت ذلك كثيراً.
الطريقة أ (بسيطة): الثوابت في ملف wp-config.php
يحرر wp-config.php وأضف فوق من عبارة "هذا كل شيء، توقف عن التحرير!":
/** SMTP - Configuration (ne pas committer si votre wp-config est versionné) */
define('BPCAB_SMTP_ENABLED', true);
define('BPCAB_SMTP_HOST', 'smtp.votre-fournisseur.tld');
define('BPCAB_SMTP_PORT', 587); // 587 (STARTTLS) ou 465 (SMTPS)
define('BPCAB_SMTP_ENCRYPTION', 'tls'); // 'tls', 'ssl' ou '' (déconseillé)
define('BPCAB_SMTP_USERNAME', 'votre-identifiant');
define('BPCAB_SMTP_PASSWORD', 'votre-secret-long-et-unique');
/** Identité d'envoi */
define('BPCAB_SMTP_FROM_EMAIL', '[email protected]');
define('BPCAB_SMTP_FROM_NAME', 'Votre Site');
/** Options de robustesse */
define('BPCAB_SMTP_TIMEOUT', 10); // en secondes
define('BPCAB_SMTP_DEBUG', false); // true temporairement, pour diagnostiquer
الطريقة ب (الاحترافية): المتغيرات البيئية
في الاستضافة المُدارة (أو عبر Docker)، استخدم متغيرات البيئة. يقرأها مُلحق MU الخاص بك بالفعل عبر getenv()أمثلة:
export BPCAB_SMTP_ENABLED=1
export BPCAB_SMTP_HOST="smtp.votre-fournisseur.tld"
export BPCAB_SMTP_PORT="587"
export BPCAB_SMTP_ENCRYPTION="tls"
export BPCAB_SMTP_USERNAME="votre-identifiant"
export BPCAB_SMTP_PASSWORD="votre-secret"
export BPCAB_SMTP_FROM_EMAIL="[email protected]"
export BPCAB_SMTP_FROM_NAME="Votre Site"
export BPCAB_SMTP_TIMEOUT="10"
export BPCAB_SMTP_DEBUG="0"
النتيجة المتوقعة: لديك الآن قيم التكوين متاحة، ولكن لم يتم ربط SMTP بـ PHPMailer بعد.
الخطوة الرابعة: قفل عنوان المرسل/عنوان الرد ومنع إعادة الكتابة
قبل حتى تهيئة بروتوكول SMTP، أقوم بفرض هوية المرسل. وإلا، ستواجه مشكلة "يعمل بروتوكول SMTP، لكن المرسل يتغير" بسبب:
- إضافة نموذج تفرض من,
- أداة بناء تقوم بحقن الرد على غريب،
- قالب يقوم بالتصفية
wp_mail_from.
أضف إلى نهاية ملفك bpcab-smtp.php :
/**
* Force l'email "From" pour éviter les réécritures incohérentes.
* Attention : certains SMTP refusent un From hors domaine autorisé.
*/
add_filter('wp_mail_from', function ($from_email) {
$configured = bpcab_smtp_get_config('from_email', '');
if (!empty($configured) && is_string($configured)) {
return $configured;
}
return $from_email;
}, 9999);
/**
* Force le nom "From".
*/
add_filter('wp_mail_from_name', function ($from_name) {
$configured = bpcab_smtp_get_config('from_name', '');
if (!empty($configured) && is_string($configured)) {
return $configured;
}
return $from_name;
}, 9999);
لماذا الأولوية؟ 9999 لأن العديد من الإضافات تتصل في وقت مبكر. هنا، أفضل أن "أفوز" في النهاية. إذا كانت لديك حاجة محددة (مثلًا، يحتاج WooCommerce إلى استخدام حقل "من" مختلف)، يمكنك حينها تعديله باستهداف عناوين بريد إلكتروني معينة فقط.
النتيجة المتوقعة: إرسال رسائل البريد الإلكتروني عبر wp_mail() سيكون لديه عنوان من ثابت (حتى قبل SMTP).
الخطوة 5: إضافة سجلات قابلة للاستخدام (دون تسريب معلومات سرية)
عند فشل بروتوكول SMTP، نادرًا ما يظهر الخطأ المفيد في لوحة التحكم. بل يظهر في مخرجات PHPMailer. أقوم بتسجيل أمرين:
- الأخطاء (مع الرسالة)،
- السياق الأدنى (المضيف/المنفذ/التشفير)، بدون اسم المستخدم/كلمة المرور.
أضف هذا الكود:
/**
* Petit logger : écrit dans error_log.
* Si WP_DEBUG_LOG est activé, ça ira dans wp-content/debug.log.
*/
function bpcab_smtp_log(string $message, array $context = []): void {
$prefix = '[BPCAB SMTP] ';
$line = $prefix . $message;
if (!empty($context)) {
// On évite d'exposer des secrets : pas de password, pas de body complet.
unset($context['password'], $context['pass'], $context['smtp_password']);
$line .= ' ' . wp_json_encode($context, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
}
error_log($line);
}
/**
* Loggue les échecs de wp_mail.
* Doc : wp_mail_failed reçoit un WP_Error.
*/
add_action('wp_mail_failed', function ($wp_error) {
if (!($wp_error instanceof WP_Error)) {
return;
}
bpcab_smtp_log('wp_mail_failed', [
'error_code' => $wp_error->get_error_code(),
'error_message' => $wp_error->get_error_message(),
'error_data' => $wp_error->get_error_data(),
]);
});
النتيجة المتوقعة: في حال فشل عملية الإرسال، ستظهر لك رسالة في سجلات PHP الخاصة بك (أو wp-content/debug.log (في حالة التفعيل).
الخطوة 6: أضف صفحة "اختبار SMTP" الإدارية (مع رمز التحقق) للتحقق من الصحة
أفضّل إجراء اختبار "داخل ووردبريس" بدلاً من اختبار خارجي، لأنه يتحقق من صحة المسار الفعلي: wp_mail() → PHPMailer → SMTP. وهذا يتجنب الخطأ الشائع: "يعمل SMTP في سطر الأوامر، لكن ووردبريس خلف ذاكرة تخزين مؤقتة/إعدادات مختلفة".
أضف صفحة في الأدوات ← اختبار SMTP
الصقه في نهاية إضافة MU:
/**
* Ajoute une page Outils > Test SMTP.
*/
add_action('admin_menu', function () {
add_management_page(
'Test SMTP',
'Test SMTP',
'manage_options',
'bpcab-smtp-test',
'bpcab_smtp_render_test_page'
);
});
/**
* Affiche la page de test.
*/
function bpcab_smtp_render_test_page(): void {
if (!current_user_can('manage_options')) {
wp_die('Accès refusé.');
}
$enabled = bpcab_smtp_is_enabled();
// Traitement du formulaire.
$result_html = '';
if (isset($_POST['bpcab_smtp_action']) && $_POST['bpcab_smtp_action'] === 'send_test') {
check_admin_referer('bpcab_smtp_send_test', 'bpcab_smtp_nonce');
$to = isset($_POST['bpcab_smtp_to']) ? sanitize_email(wp_unslash($_POST['bpcab_smtp_to'])) : '';
if (empty($to) || !is_email($to)) {
$result_html = '<div class="notice notice-error"><p>Adresse email de test invalide.</p></div>';
} else {
$subject = sprintf('[%s] Test SMTP', wp_specialchars_decode(get_bloginfo('name'), ENT_QUOTES));
$body = "Email de test envoyé par WordPress.nnDate: " . gmdate('c') . "nSite: " . home_url();
$sent = wp_mail($to, $subject, $body);
if ($sent) {
$result_html = '<div class="notice notice-success"><p>Email envoyé. Vérifiez la boîte de réception (et les spams).</p></div>';
} else {
$result_html = '<div class="notice notice-error"><p>Échec d’envoi. Vérifiez vos logs (debug.log / logs PHP).</p></div>';
}
}
}
$host = (string) bpcab_smtp_get_config('host', '');
$port = (string) bpcab_smtp_get_config('port', '');
$enc = (string) bpcab_smtp_get_config('encryption', '');
echo '<div class="wrap">';
echo '<h1>Test SMTP</h1>';
echo $enabled
? '<p><strong>SMTP activé</strong>.</p>'
: '<p><strong>SMTP désactivé</strong> (BPCAB_SMTP_ENABLED).</p>';
echo '<p>Configuration détectée :<br>';
echo '<code>' . esc_html($host) . ':' . esc_html($port) . ' (' . esc_html($enc) . ')</code></p>';
echo $result_html;
echo '<form method="post">';
wp_nonce_field('bpcab_smtp_send_test', 'bpcab_smtp_nonce');
echo '<input type="hidden" name="bpcab_smtp_action" value="send_test">';
echo '<table class="form-table" role="presentation"><tbody>';
echo '<tr><th scope="row"><label for="bpcab_smtp_to">Envoyer à</label></th>';
echo '<td><input name="bpcab_smtp_to" id="bpcab_smtp_to" type="email" class="regular-text" required placeholder="[email protected]"></td></tr>';
echo '</tbody></table>';
submit_button('Envoyer un email de test');
echo '</form>';
echo '</div>';
}
النتيجة المتوقعة: ستظهر لك في لوحة التحكم الخاصة بالمسؤول الأدوات ← اختبار SMTPيمكنك إرسال بريد إلكتروني تجريبي واستلام رسالة نجاح/فشل.
النتيجة الكاملة
لا يزال الجزء الأساسي مفقودًا: ربط PHPMailer عبر SMTP. إليكم الإضافة الكاملة لـ MU، جاهزة للنسخ واللصق، ومتوافقة مع WordPress 6.9.4 والإصدارات الأحدث وPHP 8.1 والإصدارات الأحدث.
إنشاء/استبدال wp-content/mu-plugins/bpcab-smtp.php مع هذا:
<?php
/**
* Plugin Name: BPCAB SMTP (MU)
* Description: Configuration SMTP sans plugin via PHPMailer pour WordPress 6.9.4+.
* Author: Votre Nom
* Version: 1.0.0
*
* Installation :
* - Placez ce fichier dans wp-content/mu-plugins/bpcab-smtp.php
* - Ajoutez les constantes dans wp-config.php (ou variables d'environnement)
*/
defined('ABSPATH') || exit;
/**
* Récupère une valeur de configuration SMTP depuis :
* 1) une constante (wp-config.php)
* 2) une variable d'environnement
*/
function bpcab_smtp_get_config(string $key, $default = null) {
$const = 'BPCAB_SMTP_' . strtoupper($key);
if (defined($const)) {
return constant($const);
}
$env = getenv($const);
if ($env !== false && $env !== '') {
return $env;
}
return $default;
}
/**
* Active/désactive SMTP.
*/
function bpcab_smtp_is_enabled(): bool {
return (bool) bpcab_smtp_get_config('enabled', false);
}
/**
* Logger minimal.
*/
function bpcab_smtp_log(string $message, array $context = []): void {
$prefix = '[BPCAB SMTP] ';
$line = $prefix . $message;
if (!empty($context)) {
unset($context['password'], $context['pass'], $context['smtp_password']);
$line .= ' ' . wp_json_encode($context, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
}
error_log($line);
}
/**
* Force l'email From.
*/
add_filter('wp_mail_from', function ($from_email) {
$configured = bpcab_smtp_get_config('from_email', '');
if (!empty($configured) && is_string($configured)) {
return $configured;
}
return $from_email;
}, 9999);
/**
* Force le nom From.
*/
add_filter('wp_mail_from_name', function ($from_name) {
$configured = bpcab_smtp_get_config('from_name', '');
if (!empty($configured) && is_string($configured)) {
return $configured;
}
return $from_name;
}, 9999);
/**
* Configure PHPMailer pour utiliser SMTP.
* Hook officiel : phpmailer_init.
*/
add_action('phpmailer_init', function ($phpmailer) {
if (!bpcab_smtp_is_enabled()) {
return;
}
// Sécurité : on vérifie qu'on a bien un objet PHPMailer.
if (!is_object($phpmailer) || !method_exists($phpmailer, 'isSMTP')) {
bpcab_smtp_log('PHPMailer non disponible, impossible de configurer SMTP.');
return;
}
$host = (string) bpcab_smtp_get_config('host', '');
$port = (int) bpcab_smtp_get_config('port', 587);
$enc = (string) bpcab_smtp_get_config('encryption', 'tls');
$user = (string) bpcab_smtp_get_config('username', '');
$pass = (string) bpcab_smtp_get_config('password', '');
$timeout = (int) bpcab_smtp_get_config('timeout', 10);
$debug = (bool) bpcab_smtp_get_config('debug', false);
if ($host === '') {
bpcab_smtp_log('SMTP activé mais host vide. Vérifiez BPCAB_SMTP_HOST.');
return;
}
// Bascule en SMTP.
$phpmailer->isSMTP();
$phpmailer->Host = $host;
$phpmailer->Port = $port;
// Auth si username fourni (certains relais internes n'en ont pas besoin).
$phpmailer->SMTPAuth = ($user !== '');
if ($phpmailer->SMTPAuth) {
$phpmailer->Username = $user;
$phpmailer->Password = $pass;
}
// Encryption : 'tls' (STARTTLS) ou 'ssl' (SMTPS). Vide = pas de chiffrement (déconseillé).
$enc = strtolower(trim($enc));
if (in_array($enc, ['tls', 'ssl'], true)) {
$phpmailer->SMTPSecure = $enc;
} else {
$phpmailer->SMTPSecure = '';
}
$phpmailer->Timeout = $timeout;
/**
* Debug SMTP :
* - À utiliser temporairement.
* - On loggue dans error_log, pas à l'écran.
*/
if ($debug) {
$phpmailer->SMTPDebug = 2; // 1 = client, 2 = client+serveur
$phpmailer->Debugoutput = function ($str, $level) use ($host, $port, $enc) {
bpcab_smtp_log('SMTP debug', [
'level' => $level,
'message' => $str,
'host' => $host,
'port' => $port,
'encryption' => $enc,
]);
};
}
/**
* TLS moderne : options par défaut raisonnables.
* Si vous avez des erreurs de certificat, ne "désactivez" pas la vérification en prod.
* Corrigez plutôt votre CA bundle / votre fournisseur.
*/
$phpmailer->SMTPOptions = [
'ssl' => [
'verify_peer' => true,
'verify_peer_name' => true,
'allow_self_signed' => false,
],
];
// Log minimal de configuration (sans secrets).
bpcab_smtp_log('SMTP configuré', [
'host' => $host,
'port' => $port,
'encryption' => $enc,
'auth' => $phpmailer->SMTPAuth ? 'yes' : 'no',
'timeout' => $timeout,
]);
}, 10);
/**
* Loggue les échecs wp_mail.
*/
add_action('wp_mail_failed', function ($wp_error) {
if (!($wp_error instanceof WP_Error)) {
return;
}
bpcab_smtp_log('wp_mail_failed', [
'error_code' => $wp_error->get_error_code(),
'error_message' => $wp_error->get_error_message(),
'error_data' => $wp_error->get_error_data(),
]);
});
/**
* Page admin : Outils > Test SMTP
*/
add_action('admin_menu', function () {
add_management_page(
'Test SMTP',
'Test SMTP',
'manage_options',
'bpcab-smtp-test',
'bpcab_smtp_render_test_page'
);
});
function bpcab_smtp_render_test_page(): void {
if (!current_user_can('manage_options')) {
wp_die('Accès refusé.');
}
$enabled = bpcab_smtp_is_enabled();
$result_html = '';
if (isset($_POST['bpcab_smtp_action']) && $_POST['bpcab_smtp_action'] === 'send_test') {
check_admin_referer('bpcab_smtp_send_test', 'bpcab_smtp_nonce');
$to = isset($_POST['bpcab_smtp_to']) ? sanitize_email(wp_unslash($_POST['bpcab_smtp_to'])) : '';
if (empty($to) || !is_email($to)) {
$result_html = '<div class="notice notice-error"><p>Adresse email de test invalide.</p></div>';
} else {
$subject = sprintf('[%s] Test SMTP', wp_specialchars_decode(get_bloginfo('name'), ENT_QUOTES));
$body = "Email de test envoyé par WordPress.nnDate: " . gmdate('c') . "nSite: " . home_url();
$sent = wp_mail($to, $subject, $body);
if ($sent) {
$result_html = '<div class="notice notice-success"><p>Email envoyé. Vérifiez la boîte de réception (et les spams).</p></div>';
} else {
$result_html = '<div class="notice notice-error"><p>Échec d’envoi. Vérifiez vos logs (debug.log / logs PHP).</p></div>';
}
}
}
$host = (string) bpcab_smtp_get_config('host', '');
$port = (string) bpcab_smtp_get_config('port', '');
$enc = (string) bpcab_smtp_get_config('encryption', '');
echo '<div class="wrap">';
echo '<h1>Test SMTP</h1>';
echo $enabled
? '<p><strong>SMTP activé</strong>.</p>'
: '<p><strong>SMTP désactivé</strong> (BPCAB_SMTP_ENABLED).</p>';
echo '<p>Configuration détectée :<br>';
echo '<code>' . esc_html($host) . ':' . esc_html($port) . ' (' . esc_html($enc) . ')</code></p>';
echo $result_html;
echo '<form method="post">';
wp_nonce_field('bpcab_smtp_send_test', 'bpcab_smtp_nonce');
echo '<input type="hidden" name="bpcab_smtp_action" value="send_test">';
echo '<table class="form-table" role="presentation"><tbody>';
echo '<tr><th scope="row"><label for="bpcab_smtp_to">Envoyer à</label></th>';
echo '<td><input name="bpcab_smtp_to" id="bpcab_smtp_to" type="email" class="regular-text" required placeholder="[email protected]"></td></tr>';
echo '</tbody></table>';
submit_button('Envoyer un email de test');
echo '</form>';
echo '</div>';
}
التخصيص السريع
- مهلة إذا كان خادم SMTP الخاص بك بطيئًا، فقم بترقيته.
BPCAB_SMTP_TIMEOUTفي 20. - التشفير : يستخدم
tlsمن أصل 587 في 80% من الحالات.sslمن أصل 465 إذا طلب المورد ذلك. - من : يتجنب
gmail.comفي حقل "من"، إذا كنت ترسل عبر خادم SMTP الخاص بالنطاق. تفرض العديد من خوادم الترحيل سياسات DMARC صارمة.
التكيف مع Divi 5 / Elementor / Avada
خبر سار: يعمل بروتوكول SMTP على مستوى wp_mail()لذا، فهو عالمي ومتوافق مع Divi 5 وElementor وAvada. وتتعلق التعديلات بشكل أساسي بهوية الإرسال، حيث أن هذه الأدوات (أو وحدات النماذج الخاصة بها) تحدد أحيانًا عناوين محددة.
Divi 5 (وحدة نموذج الاتصال)
- يمكن لـ Divi أن تحدد الرد على بناءً على عنوان البريد الإلكتروني للزائر. احتفظ به: إنه مفيد.
- تجنب إدخال بريد الزائر الإلكتروني من (هذا يُعطّل بروتوكول SPF/DMARC). فلترك
wp_mail_fromهذا تحديداً ما يمنع حدوث هذا الوضع.
إذا لاحظت أن Divi لا يزال يُجبر حقل "من"، فغالبًا ما يكون ذلك بسبب فلتر متأخر. في هذه الحالة، حافظ على أولوية الحقل. 9999 (تم ذلك بالفعل) وتحقق من عدم وجود أي مكون إضافي "مقتطفات" يقوم بإعادة الكتابة خلفها.
Elementor (أداة النموذج / نماذج Elementor Pro)
- يمكن لـ Elementor Pro إرسال الرسائل عبر "PHP Mail" أو "SMTP" حسب الإعدادات. إذا كنت تستخدم هذه الإضافة متعددة الاستخدامات، فاحرص على إبقاء Elementor في وضع "PHP Mail" لتجنب تكرار الإعدادات.
- احتفظ الرد على = بريد الزائر الإلكتروني، و من = نطاقك.
أفادا (Fusion Builder / نماذج Avada)
- قد تحتوي لوحة تحكم Avada أحيانًا على خيارات البريد الإلكتروني. قم بتعطيل أي خيارات SMTP داخلية إن وجدت لتجنب وجود طبقتين من SMTP.
- إذا تم إرسال رسائل البريد الإلكتروني ولكنها انتهت في مجلد البريد العشوائي، فغالبًا ما تكون المشكلة في نظام أسماء النطاقات (SPF/DKIM/DMARC)، وليس في ووردبريس.
الفحص النهائي
- مكن
BPCAB_SMTP_ENABLEDàtrue. - اذهب الأدوات ← اختبار SMTP.
- أرسل بريدًا إلكترونيًا إلى عنوان خارجي (Gmail/Outlook) وعنوان على نفس النطاق.
- يفحص:
- تم استلامها في صندوق الوارد (أو البريد المزعج).
- من = المحدد في
wp-config.php. - في حال عدم النجاح: استشر
wp-content/debug.log(وWP_DEBUG_LOG(مفعل) أو سجلات PHP.
لإجراء اختبار أكثر "واقعية"، قم بإرسال بريد إلكتروني أصلي:
- نسيت كلمة المرور (على حساب تجريبي).
- ووكومرس: بريد إلكتروني للطلب (في بيئة تجريبية).
إذا لم تكن النتيجة كما هو متوقع
إليكم مخطط تشخيصي يغطي غالبية الحالات التي أقوم باستكشاف الأخطاء وإصلاحها في بيئة الإنتاج.
| عرض | السبب المحتمل | التحقق | الحلول |
|---|---|---|---|
| فشل فوري، لا يحدث شيء | تم حظر منفذ SMTP بواسطة مزود خدمة الاستضافة | nc -vz host 587 فشل |
اطلب فتح المنفذ الصادر، أو استخدم خادم SMTP الخاص بمزود الاستضافة/مرحل على منفذ معتمد. |
| خطأ "تعذر المصادقة" | اسم المستخدم/كلمة المرور غير صحيحين، أو يلزم المصادقة. | سجلات wp_mail_failed / تصحيح أخطاء SMTP |
أعد إنشاء كلمة مرور/مفتاح SMTP الخاص بك، وتحقق من تنسيق تسجيل الدخول (عنوان البريد الإلكتروني الكامل مقابل اسم المستخدم). |
| خطأ في شهادة TLS | حزمة شهادات المصادقة مفقودة، اعتراض بروتوكول TLS، خادم قديم | السجلات + openssl s_client |
قم بتصحيح سلسلة شهادات الخادم، وتحديث PHP/CA، ولا تقم بتعطيلها. verify_peer في الإنتاج |
| تم إرسال البريد الإلكتروني ولكن تم تصنيفه كبريد مزعج | ملفات SPF/DKIM/DMARC مفقودة أو غير متناسقة | تحليل رؤوس الرسائل المستلمة | قم بتكوين SPF/DKIM/DMARC على جانب DNS (مع موفر SMTP الخاص بك) |
| كل شيء يعمل، ثم يتوقف كل شيء بعد التحديث | تم تغيير كلمة المرور / تم تدوير السر | سجل التغييرات، السجلات | قم بتنفيذ إجراء التدوير + الاختبار (صفحة اختبار SMTP) |
قائمة التحقق السريعة لحل المشكلات
- تأكد من وجود الملف في
wp-content/mu-plugins/(ليس في أي مكان آخر). - تفعيل مؤقت
BPCAB_SMTP_DEBUGàtrueثم قم بإجراء اختبار آخر. - تحقق من إصدار PHP (8.1+) وامتداد OpenSSL النشط.
- قم بمسح ذاكرة التخزين المؤقت إذا كنت تستخدم ذاكرة تخزين مؤقت للكائنات الدائمة أو إضافة تخزين مؤقت (بروتوكول SMTP نفسه ليس "ذاكرة تخزين مؤقت"، لكنني رأيت بيئات حيث يكون التكوين
wp-config.phpلم يكن هو المتوقع على العقدة).
الأخطاء الشائعة والمزالق
| خطأ | سبب | الحلول |
|---|---|---|
انسخ الكود إلى functions.php |
تغيير السمة = فقدان SMTP | استخدم إضافة MU (أو إضافة مخصصة) |
| شاشة بيضاء بعد اللصق | خطأ في بناء الجملة (فاصلة منقوطة/أقواس)، لغة PHP قديمة جدًا | تحقق من سجلات PHP، وقم بالرجوع إلى PHP 8.1+، وقم بتصحيح بناء الجملة. |
| تم تكوين SMTP ولكن من "غريب" | إضافة فلترة wp_mail_from بعدك |
احتفظ بالأولوية 9999، أو استهدف رسائل البريد الإلكتروني باستخدام فلاتر محددة. |
استعمال ssl على المنفذ 587 |
الخلط بين بروتوكول SSL الضمني وبروتوكول STARTTLS | المنفذ 587 = tlsالمنفذ 465 = ssl (باستثناء استثناءات الموردين) |
| قم بتفعيل خاصية تصحيح الأخطاء في بيئة الإنتاج ثم انسَ الأمر. | سجلات ضخمة، تسريب معلومات | تصحيح مؤقت، ثم BPCAB_SMTP_DEBUG=false |
| اتبع شرحًا قديمًا يقوم بتعديل PHPMailer مباشرةً | الكود قديم، ويتسبب في فشل التحديثات | استعمال phpmailer_init (واجهة برمجة تطبيقات ووردبريس مستقرة) |
بديل / متغير
بديل "بدون كتابة كود": إضافة SMTP
إذا كنت تفضل واجهة مستخدم مدمجة واختبارات، فقد يكون من الأسهل تفويض استخدام إضافة SMTP قوية إلى شخص غير مطور. ابحث عن إضافة يتم تحديثها باستمرار، ومتوافقة مع ووردبريس 6.9.4، والتي:
- يدعم بروتوكول OAuth2 إذا كنت تستخدم Gmail/Microsoft (يتجنب كلمات المرور الخاصة بالتطبيقات)،
- يدير السجلات بشكل صحيح
- لا يضيف تتبعًا متطفلًا.
ما زلت أحتفظ بملحق MU للمواقع "الاحترافية": مساحة سطح أقل، واجهة مستخدم أقل، مفاجآت أقل.
بديل أكثر تطوراً: موفر واجهة برمجة التطبيقات (HTTP) بدلاً من SMTP
بالنسبة للأحجام الكبيرة، غالبًا ما تكون واجهة برمجة تطبيقات HTTP الخاصة بمزود الخدمة (مثل SendGrid/Mailgun/إلخ) أكثر موثوقية من SMTP (إعادة المحاولات، والحالات، وخطافات الويب). في هذه الحالة، أنت تتجاوز سيناريو "عدم وجود إضافة" إلا إذا قمت بتطوير إضافة مصغرة مخصصة.
نصائح السلامة والأداء والصيانة
- أسرار إذا كنت
wp-config.phpإذا كان الملف مُؤرشفًا (وهذا نادر الحدوث)، فلا تضع كلمة المرور هناك. استخدم متغيرات البيئة. - لا تقم بتعطيل التحقق من بروتوكول TLS قيد الإنتاج. إذا كنت تميل إلى وضع
verify_peer=falseأنت تخفي مشكلة حقيقية (مرجع مصدق مفقود، هجوم الوسيط، شهادة منتهية الصلاحية). - مراقبة : يترك
wp_mail_failedتم تسجيل الدخول. هذا سينقذك في حال فشلت عملية إعادة تعيين كلمة المرور. - هاملت يُضيف بروتوكول SMTP زمن استجابة للشبكة. بالنسبة للمواقع التي حصن حركة المرور (على سبيل المثال، WooCommerce + أحجام كبيرة)، أو الاستعانة بمصادر خارجية للإرسال (قائمة الانتظار) أو استخدام موفر واجهة برمجة التطبيقات (API).
- الدورية وثّق موقع إضافة MU. لقد توليت إدارة مواقع لم يكن أحد يعلم أن إضافة MU تفرض استخدام SMTP، وكان الجميع يلقي باللوم على "ووردبريس".
لتذهب أبعد من ذلك
- أضف القائمة البيضاء رسائل البريد الإلكتروني (على سبيل المثال، تفعيل SMTP فقط في بيئة الإنتاج، أو فقط لنطاقات مستلمين معينة في بيئة الاختبار).
- أضف فلترًا للإدارة من مختلف بحسب نوع البريد الإلكتروني (ووكومرس مقابل نموذج)، من خلال الفحص
$subjectأو عن طريق إدخال الرؤوس عبرwp_mail. - اكتب السجلات إلى ملف مخصص (عبر Monolog) بدلاً من
error_log، إذا سمحت بنيتك التحتية بذلك. - أضف تنبيهًا (عبر سلاك/البريد الإلكتروني) إذا
wp_mail_failedيحدث N مرة في 10 دقائق.
الموارد
- wp_mail() — مرجع رسمي
- Hook phpmailer_init — مرجع رسمي
- إضافات أساسية للاستخدام — WordPress.org
- wordpress-develop (مصدر ووردبريس) — جيت هاب
- دالة getenv() — PHP.net
- OpenSSL — PHP.net
- نظام تتبع التغييرات الأساسية في ووردبريس (لتتبع التغييرات المتعلقة بـ wp_mail/PHPMailer)
الأسئلة الشائعة
هل تحل هذه الطريقة محل mail() ?
نعم، طالما أن رسائلك الإلكترونية تصل wp_mail()يستخدم ووردبريس PHPMailer و Hook phpmailer_init يتيح لك ذلك التبديل إلى بروتوكول SMTP قبل الإرسال.
لماذا استخدام إضافة MU بدلاً من إضافة كلاسيكية؟
لأنها إعدادات "بنية تحتية": يتم تحميلها دائمًا، ولا يمكن تعطيلها عن طريق الخطأ، وهي مستقلة عن القالب. تجدون توثيق إضافات MU هنا: developer.wordpress.org.
هل يمكنني استخدام بروتوكول SMTP الخاص بـ Gmail؟
من الناحية التقنية، نعم، ولكن في عام 2026، غالباً ما يكون الأمر معقداً بدون بروتوكول OAuth2 (كلمات مرور خاصة بالتطبيقات، وقيود). بالنسبة لموقع ويب احترافي، يُعدّ خادم SMTP مخصص (أو موفر خدمة بريد إلكتروني للمعاملات) أكثر استقراراً.
لماذا فرض النموذج بدلاً من ترك المكون الإضافي للنموذج يحدده؟
لأن وضع بريد الزائر الإلكتروني في حقل "من" غالبًا ما يُخلّ ببروتوكولات SPF/DMARC ويزيد من الرسائل المزعجة. بدلًا من ذلك، احتفظ ببريد الزائر الإلكتروني في الرد على.
لقد استلمت البريد الإلكتروني ولكنه موجود في مجلد الرسائل غير المرغوب فيها: هل المشكلة في الكود؟
نادرًا ما يحدث ذلك. في أغلب الأحيان، يكون السبب متعلقًا بنظام أسماء النطاقات (DNS): بروتوكولات SPF/DKIM/DMARC، أو سمعة عنوان IP، أو عنوان المرسل غير المتوافق مع النطاق. يضمن رمز SMTP بشكل أساسي إمكانية تسليم الرسائل، وليس السمعة.
هل أحتاج إلى التفعيل؟ BPCAB_SMTP_DEBUG دائمًا ؟
لا. قم بتفعيله لأغراض التشخيص فقط، ثم قم بتعطيله. قد تصبح سجلات SMTP كبيرة الحجم وتكشف تفاصيل عن بنيتك التحتية.
ماذا أفعل إذا كان مزود استضافة موقعي الإلكتروني يحظر المنفذ 587؟
استخدم بروتوكول SMTP الذي يوفره مزود الاستضافة (والذي غالبًا ما يكون مصرحًا به داخليًا)، أو اطلب فتح المنفذ، أو استخدم مزودًا يدعم منفذًا مصرحًا به بديلًا.
هل هو متوافق مع ووكومرس؟
نعم. يقوم ووكومرس بالإرسال عبر wp_mail() (باستثناء التخصيص). اختبر رسالة البريد الإلكتروني الخاصة بالطلب في بيئة تجريبية للتحقق من صحتها.
هل يمكن أن يؤدي هذا إلى تعطيل خدمة البريد الإلكتروني للنظام (إعادة تعيين كلمة المرور)؟
نعم، في حال كانت بيانات اعتماد SMTP غير صحيحة أو كان الخادم غير متاح. احتفظ بصفحة "اختبار SMTP" وإجراءات التراجع: ضع BPCAB_SMTP_ENABLED à false مؤقتا.
لماذا لا يتم تعطيل التحقق من بروتوكول TLS إذا واجهت خطأ في الشهادة؟
لأنك بذلك تفتح الباب أمام عمليات الاختراق. بدلاً من ذلك، قم بإصلاح السبب: حزمة شهادات المرجع المصدق من جانب الخادم، أو شهادة الموفر، أو خادم وكيل يقوم بفحص بروتوكول أمان طبقة النقل (TLS).
كيف يمكنني معرفة ما إذا تم تحميل إضافة MU بشكل صحيح؟
في لوحة التحكم، انتقل إلى ملحقات تظهر إضافات MU في تبويب/قسم مخصص حسب واجهة المستخدم. وإلا، فأنشئ سجلًا عمدًا. bpcab_smtp_log('MU-plugin chargé'); وتحقق من سجلاتك.