افتح
قريب

إرسال رسائل البريد الإلكتروني مع php. إرسال رسائل بريد إلكتروني باستخدام php Infernal inurl sendmail php

تكوين خادم بريد الإرسال (حل مشكلة إرسال البريد من البرامج النصية)

في بعض الحالات ، يحدث أن خادم بريد Sendmail لا يرسل البريد ، ويعيد الخطأ:

28 فبراير 22:04:24 myhost sendmail: mATM4O8w58065806: Losing ./qfmATM4O8w58065806: Savemail panic Feb 28 22:04:24 myhost sendmail: mATM4O8w58065806: SYSERR (www): savemail: لا يمكن حفظ البريد الإلكتروني المرفوض في أي مكان

أيضًا في السجلات قد يكون هناك خطأ مثل:

Stat = خطأ في تنسيق البيانات

تحدث المشكلة عادةً بسبب عدم وجود اسم مضيف للخادم ، أو عدم وجود عنوان بريدي عند الإرسال.

في مثل هذه الحالات ، يجب عليك تحديد عنوان بريدي موجود. في ISPmanager ، يمكن تحديده في خصائص مجال WWW في حقل "البريد الإلكتروني للمسؤول".

عند تحديد العنوان في تكوين خادم الويب Apache في وصف المضيف الظاهري:

php_admin_value sendmail_path "/ usr / sbin / sendmail -t -i -f [بريد إلكتروني محمي]"

إذا تم استخدام PHP في وضع CGI أو FastCGI ، تتم كتابة الإدخال في الملف ~ / php-bin / php.ini

Sendmail_path = "/ usr / sbin / sendmail -t -i -f [بريد إلكتروني محمي]"

تعطيل التحقق من صحة عنوان المرسل عند إرسال البريد

يبدأ Sendmail ببرنامج إرسال الرسائل (MSP) افتراضيًا. هذه عملية منفصلة لمعالجة قائمة انتظار البريد.

ضع في اعتبارك تعطيله على نظام FreeBSD

اكتب سطرًا في ملف /etc/make.conf يعطل الإنشاء التلقائي لملف submit.cf

SENDMAIL_SET_USER_ID = نعم

بعد ذلك ، تحتاج إلى حذف ملف submit.cf ، وتغيير الحقوق إلى ملف sendmail القابل للتنفيذ (ضع SUID بت عليه بدلاً من SGID ، أي ، قم بتعيين الحقوق إلى 4755 بدلاً من 2755) وأعد تشغيل Sendmail

يتأثر سلوك هذه الوظائف بالإعدادات في ملف php.ini.

خيارات تكوين البريد
اسم تقصير قابل للتغيير التغيير
mail.add_x_header "0" PHP_INI_PERDIR متاح منذ PHP 5.3.0.
سجل الإلكتروني باطل PHP_INI_PERDIR متاح منذ PHP 5.3.0. (PHP_INI_SYSTEM | PHP_INI_PERDIR)
mail.force_extra_parameters باطل PHP_INI_PERDIR متاح منذ PHP 5.0.0. (PHP_INI_SYSTEM | PHP_INI_PERDIR)
SMTP "مضيف محلي" PHP_INI_ALL
smtp_port "25" PHP_INI_ALL
sendmail_from باطل PHP_INI_ALL
sendmail_path "/ usr / sbin / sendmail -t -i" PHP_INI_SYSTEM
لمزيد من التفاصيل والتعريفات الخاصة بأوضاع PHP_INI_ * ، ​​راجع ملف.

فيما يلي شرح موجز لتوجيهات التكوين.

يضيف X-PHP- الأصل- البرنامج النصيسيشمل UID للبرنامج النصي متبوعًا باسم الملف.

سجل الإلكتروني سلسلة

المسار إلى ملف السجل الذي سيتم تسجيل الكل بريد()المكالمات. تتضمن إدخالات السجل المسار الكامل للنص ، ورقم السطر ، لالعنوان والعناوين.

Mail.force_extra_parameters سلسلة

فرض إضافة المعامِلات المحددة لتمريرها كمعلمات إضافية إلى ملف sendmail الثنائي. ستحل هذه المعلمات دائمًا محل قيمة المعلمة الخامسة إلى بريد()، حتى في الوضع الآمن.

SMTP سلسلة

يُستخدم ضمن Windows فقط: اسم المضيف أو عنوان IP لخادم SMTP يجب أن يستخدم PHP للبريد المرسل بامتداد بريد()وظيفة.

smtp_port int

مستخدم تحت Windows فقط: رقم المنفذ للاتصال بالخادم المحدد بامتداد SMTPالضبط عند إرسال البريد باستخدام بريد()؛ افتراضات إلى 25.

sendmail_from سلسلة

أي من:يجب استخدام عنوان البريد في البريد المرسل من PHP ضمن Windows. يعين هذا التوجيه أيضًا "مسار العودة:"رأس.

sendmail_path سلسلة

أين ال ارسل بريديمكن العثور على البرنامج ، عادةً / usr / sbin / sendmail أو / usr / lib / sendmail. تهيئةيقوم بمحاولة صادقة لتحديد موقع هذا لك وتعيين افتراضي ، ولكن إذا فشلت ، يمكنك تعيينه هنا.

أنظمة لا تستخدم ارسل بريديجب تعيين هذا التوجيه لغلاف الإرسال / استبدال عروض نظام البريد الخاصة بهم ، إن وجدت. على سبيل المثال ، »يمكن لمستخدمي Qmail عادةً ضبطه على / var / qmail / bin / sendmail أو / var / qmail / bin / qmail-injection.

qmail- حقنلا يتطلب أي خيار لمعالجة البريد بشكل صحيح.

يعمل هذا التوجيه أيضًا تحت Windows. في حالة الضبط ، يتم تجاهل smtp و smtp_port و sendmail_from ويتم تنفيذ الأمر المحدد.

منذ 5 سنوات

في Ubuntu 13.04 ، لست متأكدًا من التوزيعات الأخرى.

إذا قمت ببساطة بإلغاء التعليق الافتراضي:

sendmail_path = "sendmail -t -i"

ستفشل وظائف البريد () الخاصة بك. هذا لأنه ، يجب عليك وضع المسار الكامل (على سبيل المثال / usr / sbin / sendmail -t -i)

توضح الوثائق أن PHP تحاول أن تجد مسار الإرسال الصحيح ، لكنها فشلت بشكل واضح بالنسبة لي.

لذلك ، أدخل دائمًا FULLPATH لإرسال بريد أو قد تحصل على نتائج فاشلة غير متوقعة.

كملاحظة ثانوية: أولئك الذين يريدون فقط ENFORCE المعامل -f ، يمكنك القيام بذلك في php.ini باستخدام:

mail.force_extra_parameters = [بريد إلكتروني محمي]

يمكنك ترك مسار الإرسال معلقًا ، وسيظل يستخدم الإعدادات الافتراضية (ضمن خيارات UNIX -t -i التي إذا بحثت عنها تعتبر مهمة جدًا لتعيينها) ....

ولكن الآن لا توجد طريقة لتغيير هذا ، حتى مع الوسيطة الخامسة لوظيفة mail (). -f مهم ، لأنه إذا لم يتم تعيينه ، فسيتم تعيينه على أي مستخدم يعمل البرنامج النصي PHP تحته ، وقد لا ترغب في ذلك.

أيضًا ، -f يعين Return-Path: header الذي يستخدم كعنوان Bounce ، في حالة حدوث أخطاء ، حتى تتمكن من معالجتها. لا يمكنك تعيين مسار الإرجاع: في رؤوس البريد () لسبب ما ... كان بإمكانك ذلك من قبل. الآن عليك استخدام الخيار -f.

منذ عامين

إذا تلقى أي شخص رسالة الخطأ المشفرة هذه في سجلات أخطاء PHP:
"sh: -t: الأمر غير موجود"
بعد الترقية من PHP 5.4 ، قد يكون هذا هو الحل المناسب لك.

لقد قمت بترقية PHP من 5.4 إلى 5.6 وجميع وظائف mail () لدينا تعطلت فجأة ، بدون تسجيل أخطاء مفيد.

ملف ini يتم تجاهله الآن إذا كنت تستخدم ini_set () لتحديد مسار إلى ملف sendmail الثنائي سريعًا.

لذا ، فقط حدد "sendmail_path" في php.ini بدلاً من ذلك. هذا كل ما في الأمر - لقد أصلح جميع وظائف البريد () بالنسبة لنا.

آمل أن توفر هذه الملاحظة الصغيرة لشخص آخر الكثير من الوقت الذي قضيته في استكشاف الأخطاء وإصلاحها والبحث. هتافات!

منذ 3 سنوات

تحديد مسار العودة:

لا يعمل رأس مسار الإرجاع لأنه ليس جزءًا من بروتوكول smtp.

يمكن تعيين * nix -f على أمر البريد
بدلا من ذلك
تقبل بعض MTAs رأس "من" بنمط mbox على سطر الرأس الأول
ملاحظة: لا توجد نقطتان بعد "من" ، يجب أن تكون سطر العنوان الأول
أو قد تتمكن من إعادة تكوين MTA لتفسير رؤوس مسار الإرجاع

F هي الطريقة الأكثر موثوقية ولكنها قد تعني أنه لا يمكنك تعيين أي خيار سطر أوامر آخر بسبب مشاكل الهروب من shell.

لاحظ أيضًا أن متطلبات تنسيق البريد الإلكتروني تختلف بين النوافذ وكل شيء آخر. يتوقع sendmail نهايات الأسطر \ n فقط

في كل مرة أقوم فيها بإعداد خادم ويب محلي ، أجد سؤالاً حول كعب روتين لـ Sendmail.

يوجد حل رائع لنظام التشغيل Windows: Sendmail وهمية للنوافذ(sendmail.exe) http://glob.com.au/sendmail/
هناك مقال على حبري عن هذا الحل: بريد PHP تحت Windows http://habrahabr.ru/post/26518/
حل آخر لنظام التشغيل Windows: اختبار أداة خادم البريد http://www.toolheap.com/test-mail-server-tool/
يوجد أيضًا مقال لمستخدمي Linux: كعب إرسال بريد لينكس http://habrahabr.ru/post/49665/

أنا شخصياً أحببت حل PHP النقي أكثر ، والذي سيتم مناقشته أكثر.

من الايجابيات:

  • لا توجد خدمات طرف ثالث
  • حل عبر الأنظمة الأساسية لنظام التشغيل المثبت عليه PHP
  • الحد الأدنى لحجم ملف كعب الروتين
  • كل منطق كعب روتين قابل للتعديل في PHP
  • حفظ رسالة في ملف

من السلبيات:

  • لا إعادة توجيه إلى صندوق بريد حقيقي

قائمة الحجج والخيارات كعب روتين:

  • - دير<Путь к папке> - مجلد للملفات
  • --ملف<имя файла> - احفظ كل رسالة في ملف مشترك محدد
  • - مُسبَق- اضافة رسالة جديدة الى بداية الملف المشترك
  • --افتح- فتح ملف الرسائل تلقائيًا في برنامج "المفكرة"

خيارات ملف PHP.INI:

؛ SMTP = المضيف المحلي ؛ smtp_port = 25 ؛ sendmail_from = [بريد إلكتروني محمي] sendmail_path = "php.exe C: sendmail.php --dir C: mail --open"

إذا كان المسار إلى php.exe مسجلاً في PATH ، فلا يمكنك تحديده في PHP.INI ، وإلا فمن المستحسن تغيير php.exe إلى<Путь к папке с PHP>php.exe

Sendmail_path = "C: serverbinphpphp.exe C: sendmail.php --dir C: mail --open"

في نظام Linux ، يمكنك تحديد مسار الملف على الفور ، دون أن تنسى أن تجعله قابلاً للتنفيذ أولاً: chmod 755 Sendmail.php

Sendmail_path = "/home/someuser/sendmail.php --dir / tmp / mail"

البرنامج النصي sendmail.php نفسه:

#! / usr / local / bin / php

سأكون سعيدا إذا كان سيكون مفيدا لك.

لقد قمت مؤخرًا بإعداد خادم منزلي ، وكنت بحاجة لاختبار إرسال البريد هناك. ولكن المشكلة هي أنه عند طلب صفحة ترسل بريدًا ، ظهر خطأ 500.

مشكلة

بدأت أبحث لأرى ما يجري. لا يوجد شيء مثير للاهتمام في سجلات php-fpm ، ففي سجلات nginx يمكنك رؤية أن ملف php-fpm upstream يسقط عند انتهاء المهلة.

2013/04/18 15:28:01 6928 # 0: * 1409 انتهت مهلة التحميل (110: انتهت مهلة الاتصال) أثناء قراءة رأس الاستجابة من المنبع ، العميل: xx.xx.xx.xx ، الخادم: ، الطلب: "POST /page.php HTTP / 1.1 "، المنبع:" fastcgi: //127.0.0.1: 9010 "، المضيف:" site.ru "، المرجع:" http://site.ru "

ثم خطرت لي الفكرة للنظر في سجل النظام. هناك رأيت بعض الخطوط المثيرة للاهتمام:

سبتمبر 9 18:53:20 قائمة انتظار sm-msp الضخمة: اسم مضيفي غير المؤهل (ميجا) غير معروف ؛ نائم لإعادة المحاولة سبتمبر 9 18:54:20 قائمة انتظار sm-msp الضخمة: غير قادر على تأهيل اسم المجال الخاص بي (ميجا) - باستخدام اسم قصير

آها ، بدأ يخطئ تجاه الإرسال. أحاول إعادة تشغيله بالأمر:

إعادة تشغيل خدمة sudo sendmail

وأرى تأكيدًا لتخميني.

[بريد إلكتروني محمي]: / home / andrey # sudoservice sendmail أعد تشغيل sudo: غير قادر على حل المضيف xyz.xyz * إعادة تشغيل وكيل نقل البريد (MTA) sendmail [بريد إلكتروني محمي]: / home / andrey #

المحلول

اتضح أنه اسم الخادم. بعد أن وضعت اسم الخادم هذا (بنقطة) - كل شيء يعمل كما ينبغي.

127.0.0.1 localhost localhost.localdomain mega.foobar

شكرا!

إذا ساعدتك هذه المقالة ، أو إذا كنت تريد دعم بحثي ومدونتي ، فإليك أفضل طريقة للقيام بذلك:

مقدمة عن وظيفة php mail () ومثال بسيط لاستخدامها لإرسال رسائل البريد الإلكتروني. أيهما أفضل أم Sendmail vs mail.

تتيح لك وظيفة mail () PHP إرسال رسائل بريد إلكتروني إلى عنوان بريد إلكتروني محدد.

بناء الجملة:

منطقي بريد(سلسلة $ إلى،سلسلة الموضوع $،سلسلة رسالة $[،سلسلة رؤوس_ إضافية $[،سلسلة معلمات_إضافية بالدولار]]);

حدود:

  • ل- عنوان البريد الإلكتروني لمتلقي الخطاب بما يتوافق مع تنسيق RFC 2822. علي سبيل المثال:
  • موضوعات- موضوع الخطاب المرسل وفق تنسيق RFC 2047
  • رسالة- محتوى الرسالة المرسلة. يجب ألا يزيد طول كل سطر عن 70 حرفًا وينتهي بحرف سطر جديد (\ n).

    نوافذ فقط: عندما تستدعي PHP خادم SMTP مباشرةً ، تتم إزالة النقطة الموجودة في بداية السطر. للتغلب على هذه الفروق الدقيقة ، يجب عليك استخدام بديل لنقطة مزدوجة في بداية السطر.

    $ message = str_replace ("\ n."، "\ n .."، $ message)؛

  • رؤوس_ إضافية(اختياري) - سلسلة تضاف بعد رؤوس البريد الإلكتروني. تُستخدم عادةً لإضافة رؤوس إضافية (من ونسخة ونسخة مخفية). يجب فصل السطور بواسطة CRLF (\ r \ n).
  • معلمات_إضافية(اختياري) - معلمات إضافية يستخدمها البرنامج المخصص لإرسال رسائل البريد الإلكتروني.

عائدات: صحيحإذا تم إرسال البريد الإلكتروني بنجاح أو خاطئةان لم. وتجدر الإشارة إلى أنه إذا تم بنجاح وضع رسالة في قائمة الانتظار لإرسالها ، فهذا لا يعني أنها ستصل إلى المرسل إليه.

الآن بعد أن فهمنا النظرية ، يمكننا البدء في الممارسة. لكن أولاً ، أريد أن أقدم وظيفتين مفيدتين من شأنها أن تسهل مهمتنا إلى حد كبير.

مثال: php وظيفة MIME base64 ترميز ، نظرا لترميز

الدالة mime_base64 (سلسلة $، $ charset = "windows-1251") (إرجاع "=؟". $ charset. "؟ B؟". base64_encode (تقليم (سلسلة $)). "؟ ="؛)

إحدى المشاكل التي تظهر عند إرسال البريد هي تشكيل رأس الرسالة. على وجه الخصوص ، يمكن التعرف على أسماء الرأس والمرسلين والمستلمين المكتوبة باللغة السيريلية بواسطة عميل بريد المستلم في نموذج مشوه. لتجنب هذه المشكلة ، يمكنك استخدام تشفير base64 MIME ، والذي يحول تسلسل البايت إلى سلسلة من أحرف ASCII القابلة للطباعة.

الوظيفة is_email ($ string) (إرجاع preg_match ("/ ^ () + ([\. a-zA-Z0-9 _-]) * @ () + (\. +) * \. ((2،6)) $ / "، $ string)؛)

يتم التعامل مع هذه أيضا. والآن من أجل الذي كتبت هذه المذكرة.

مثال: إرسال رسائل البريد الإلكتروني باستخدام وظيفة php mail ()

$ charset = "windows-1251" ؛ $ from = mime_base64 ("اسم المرسل"، $ charset). " "؛ $ to = mime_base64 (" اسم جهاز الاستقبال "، $ charset)." "؛ $ subject = mime_base64 (" موضوع البريد الإلكتروني المرسل "، $ charset) ؛ $ message =" محتوى البريد الإلكتروني المرسل. "؛ $ message = wordwrap ($ message، 70)؛ $ headers =" من: ". $ from." \ r \ n "." الرد على: ". $ from." \ r \ n "." X-Mailer: PHP / ". phpversion ()." \ r \ n "." إصدار MIME: 1.0 "." \ r \ n "." نوع المحتوى: نص / عادي ؛ محارف = "". محارف $. "" ؛ if (mail ($ to، $ subject، $ message، $ headers)) (echo "

تم إرسال الرسالة.

"؛) آخر (صدى"

حدث خطأ.

"; }

أعتقد أن التعليقات لا لزوم لها ، لأنني قد أولت بالفعل اهتمامًا كافيًا للتفاصيل المختلفة. قد تختلف مجموعة رؤوس RFC ، لكن على الخادم المحلي حصلت على ما يلي:

X-Sendmail-Cmdline: sendmail.pl -t -i إلى: =؟ windows-1251؟ B؟ yOz / IO / u6 / P36PLl6 / w =؟ = الموضوع: =؟ windows-1251؟ B؟ 0uXs4CDu8u / w4OLr / + Xs7uPuIO / o8fzs4A ==؟ = من: =؟ windows-1251؟ B؟ yOz / IO7y7 / Dg4ujy5ev8؟ = الرد على: =؟ windows-1251؟ B؟ yOz / IO7y7 / Dg4ujy5ev8؟ = X-Mailer: PHP / 5.3.3 إصدار MIME: 1.0 نوع المحتوى: نص / عادي ؛ charset = "windows-1251"

sendmail مقابل بريد php ()

أخيرًا ، برنامج تعليمي صغير. Sendmail هو أحد خوادم البريد (MTAs) ، بينما تقوم وظيفة php mail () ببساطة بتنفيذ عملية إرسال رسائل البريد الإلكتروني عبر اتصال SMTP. من الواضح أن استخدام دالة php هو حل مناسب ، لكنه بعيد عن أن يكون الحل الأمثل. عادةً ما يتم استخدام mail () في الحالات التي لا نتحدث فيها عن المراسلات البريدية على نطاق واسع.