Membuka
Menutup

Mengirim email di php (sendmail) lambat. Mengatasi masalah pengiriman email dari script di Sendmail Menonaktifkan verifikasi kebenaran alamat pengirim saat mengirim email

Memperkenalkan fungsi mail() php dan contoh sederhana penggunaannya untuk mengirim email. Mana yang lebih baik atau Sendmail vs mail.

Fungsi PHP mail() memungkinkan Anda mengirim email ke alamat email tertentu.

Sintaksis:

Bodoh surat(rangkaian $ke,rangkaian $subjek,rangkaian $pesan[, rangkaian $tambahan_header[, rangkaian $parameter_tambahan]]);

Pilihan:

  • ke— alamat email penerima surat sesuai dengan format RFC 2822. Misalnya:
  • subjek— perihal surat yang dikirimkan sesuai format RFC 2047
  • pesan— isi surat yang dikirim. Setiap baris tidak boleh lebih dari 70 karakter dan diakhiri dengan karakter baris baru (\n).

    Hanya jendela: Ketika PHP mengakses server SMTP secara langsung, titik di awal baris dihilangkan. Untuk mengatasi nuansa ini, Anda harus menggunakan titik ganda di awal baris.

    $pesan = str_replace("\n.", "\n..", $pesan);

  • tambahan_header(opsional) – baris yang akan ditambahkan setelah header surat. Biasanya digunakan untuk menambahkan header tambahan (Dari, Cc dan Bcc). Garis harus dipisahkan dengan CRLF (\r\n).
  • parameter_tambahan(opsional) – parameter tambahan yang digunakan oleh program yang ditujukan untuk mengirim surat.

Kembali: BENAR jika surat berhasil dikirim atau PALSU jika tidak. Perlu diperhatikan, jika surat berhasil masuk antrian pengiriman, bukan berarti surat tersebut akan sampai ke penerima.

Sekarang setelah kita memahami teorinya, kita bisa mulai mempraktikkannya. Namun pertama-tama, saya ingin memberi Anda beberapa fungsi berguna yang akan sangat memudahkan tugas kita.

Contoh: fungsi php pengkodean MIME base64, dengan mempertimbangkan pengkodean

Fungsi mime_base64($string, $charset="windows-1251") ( mengembalikan "=?" . $charset . "?B?" . base64_encode(trim($string)) . "?="; )

Salah satu permasalahan yang muncul saat mengirim surat adalah pembentukan header surat. Secara khusus, nama header, pengirim dan penerima yang ditulis dalam Cyrillic dapat dikenali oleh klien email penerima dalam bentuk yang terdistorsi. Untuk menghindari masalah ini, Anda dapat menggunakan pengkodean MIME base64, yang mengubah rangkaian byte menjadi rangkaian karakter ASCII yang dapat dicetak.

Fungsi is_email($string) ( return preg_match("/^()+([\.a-zA-Z0-9_-])*@()+(\.+)*\.((2,6)) $/", $string); )

Ini juga telah diselesaikan. Dan sekarang, untuk itulah catatan ini ditulis.

Contoh: mengirim email menggunakan fungsi php mail()

$rangkaian karakter = "windows-1251"; $dari = mime_base64("Nama pengirim", $charset) . " "; $to = mime_base64("Nama penerima", $charset) . " "; $subject = mime_base64("Subjek pesan sedang dikirim", $charset); $message = "Isi pesan sedang dikirim."; $message = wordwrap($message, 70); $headers = "Dari: " . $from . " \r\n" . "Balas Ke: " . $from . "\r\n" . "X-Mailer: PHP/" . phpversion(). "\r\n" . " Versi MIME: 1.0" . "\r\n" . "Jenis konten: teks/polos; rangkaian karakter="" . $rangkaian karakter. """; if (mail($ke, $subjek, $pesan, $header)) ( echo "

Surat telah dikirim.

"; ) lain ( gema "

Sebuah kesalahan telah terjadi.

"; }

Saya pikir komentar tidak diperlukan, karena saya sudah menaruh banyak perhatian pada berbagai detail. Opsi untuk kumpulan header RFC mungkin berbeda, tetapi di server lokal saya mendapatkan yang berikut:

X-Sendmail-Cmdline: sendmail.pl -t -i Ke: =?windows-1251?B?yOz/IO/u6/P36PLl6/w=?= Subjek: =?windows-1251?B?0uXs4CDu8u/w4OLr/+Xs7uPuIO/o8fzs4A==?= Dari: =?windows-1251?B?yOz/IO7y7/Dg4ujy5ev8?= Balasan Ke: =?windows-1251?B?yOz/IO7y7/Dg4ujy5ev8?= X-Mailer: PHP/5.3.3 Versi MIME: 1.0 Tipe konten: teks/polos; rangkaian karakter="windows-1251"

Kirim email vs email php()

Terakhir, program pendidikan kecil. Sendmail adalah salah satu server email (MTA), sedangkan fungsi php mail() hanya mengimplementasikan proses pengiriman email melalui koneksi SMTP. Jelas bahwa menggunakan fungsi PHP itu nyaman, tetapi jauh dari itu solusi optimal. Biasanya mail() digunakan jika pengiriman surat berskala besar tidak terlibat.

Saya baru-baru ini menyiapkan server rumah, dan saya perlu menguji pengiriman email di sana. Tapi inilah masalahnya: ketika meminta halaman yang mengirim email, muncul kesalahan 500.

Masalah

Saya mulai melihat apa yang sedang terjadi. Tidak ada yang menarik di log php-fpm; di log nginx Anda dapat melihat bahwa upstream php-fpm mogok karena waktu habis.

18/04/2013 15:28:01 6928#0: *1409 waktu upstream habis (110: Waktu koneksi habis) saat membaca header respons dari upstream, klien: xx.xx.xx.xx, server:, permintaan: "POST /page.php HTTP/1.1", hulu: "fastcgi://127.0.0.1:9010", host: "site.ru", pengarah: "http://site.ru"

Dan kemudian muncul ide di benak saya untuk melihat syslog. Di sana saya melihat baris-baris menarik:

9 Sep 18:53:20 mega sm-msp-queue: Nama host saya yang tidak memenuhi syarat (mega) tidak diketahui; tidur untuk mencoba lagi 9 Sep 18:54:20 mega sm-msp-queue: tidak dapat memenuhi syarat nama domain saya sendiri (mega) -- menggunakan nama pendek

Ya, saya mulai berbuat dosa terhadap sendmail. Saya mencoba memulai ulang dengan perintah:

Layanan sudo sendmail dimulai ulang

dan saya melihat konfirmasi tebakan saya.

Andrey@mega:/home/andrey# sudoservice sendmail restart sudo: tidak dapat menyelesaikan host xyz.xyz * Memulai ulang Mail Transport Agent (MTA) sendmail andrey@mega:/home/andrey#

Larutan

Masalahnya ternyata di nama servernya. Setelah saya atur nama server seperti ini (dengan titik), semuanya berjalan sebagaimana mestinya.

127.0.0.1 localhost localhost.localdomain mega mega.foobar

Terima kasih!

Jika artikel ini membantu Anda, atau Anda ingin mendukung penelitian dan blog saya, ini dia Jalan terbaik lakukan:

Perilaku fungsi-fungsi ini dipengaruhi oleh pengaturan di php.ini.

Opsi konfigurasi email
Nama Bawaan Dapat diubah log perubahan
mail.add_x_header "0" PHP_INI_PERDIR Tersedia sejak PHP 5.3.0.
mail.log BATAL PHP_INI_PERDIR Tersedia sejak PHP 5.3.0. (PHP_INI_SYSTEM|PHP_INI_PERDIR)
mail.force_extra_parameters BATAL PHP_INI_PERDIR Tersedia sejak PHP 5.0.0. (PHP_INI_SYSTEM|PHP_INI_PERDIR)
SMTP "host lokal" PHP_INI_ALL
smtp_port "25" PHP_INI_ALL
kirimmail_dari BATAL PHP_INI_ALL
sendmail_path "/usr/sbin/sendmail -t -i" PHP_INI_SYSTEM
Untuk rincian lebih lanjut dan definisi mode PHP_INI_*, lihat .

Berikut penjelasan singkat tentang arahan konfigurasi.

Menambahkan X-PHP-Asal-Script yang akan menyertakan UID skrip diikuti dengan nama file.

Mail.log rangkaian

Jalur ke file log yang akan mencatat semuanya surat() panggilan. Entri log mencakup jalur lengkap skrip, nomor baris, Ke alamat dan header.

Mail.force_extra_parameters rangkaian

Paksa penambahan parameter tertentu untuk diteruskan sebagai parameter tambahan ke biner sendmail. Parameter ini akan selalu menggantikan nilai parameter ke-5 menjadi surat(), bahkan dalam mode aman.

SMTP rangkaian

Hanya digunakan di Windows: nama host atau alamat IP server SMTP yang harus digunakan PHP untuk email yang dikirim dengan surat() fungsi.

Smtp_port ke dalam

Hanya digunakan pada Windows: Nomor port untuk menyambung ke server yang ditentukan dengan SMTP pengaturan saat mengirim email dengan surat(); defaultnya adalah 25.

Kirimmail_dari rangkaian

Yang "Dari:" alamat email harus digunakan dalam email yang dikirim dari PHP di Windows. Arahan ini juga menetapkan "Jalur Kembali:" tajuk.

Sendmail_path rangkaian

Dimana kirim email program dapat ditemukan, biasanya /usr/sbin/sendmail atau /usr/lib/sendmail . konfigurasikan melakukan upaya jujur ​​untuk menemukan yang ini untuk Anda dan menetapkan default, tetapi jika gagal, Anda dapat mengaturnya di sini.

Sistem tidak menggunakan kirim email harus menyetel arahan ini ke pembungkus/pengganti sendmail yang ditawarkan sistem email mereka, jika ada. Misalnya, » Pengguna Qmail biasanya dapat mengaturnya ke /var/qmail/bin/sendmail atau /var/qmail/bin/qmail-inject .

qmail-inject tidak memerlukan opsi apa pun untuk memproses email dengan benar.

Arahan ini juga berfungsi di Windows. Jika disetel, smtp , smtp_port dan sendmail_from diabaikan dan perintah yang ditentukan dijalankan.

5 tahun lalu

Di Ubuntu 13.04, tidak yakin dengan Distro lainnya.

Jika Anda cukup menghapus komentar pada default:

sendmail_path = "kirim email -t -i"

Semua fungsi mail() Anda akan gagal. Ini karena, Anda harus menempatkan PATH LENGKAP (yaitu /usr/sbin/sendmail -t -i)

Dokumentasi menyatakan PHP mencoba yang terbaik untuk menemukan jalur sendmail yang benar, tetapi jelas gagal bagi saya.

Jadi, selalu masukkan FULLPATH untuk mengirim email atau Anda mungkin mendapatkan hasil gagal yang tidak terduga.

Sebagai catatan sekunder: Mereka yang hanya ingin MEMPERLAKUKAN parameter -f, Anda dapat melakukannya di php.ini menggunakan:

mail.force_extra_parameters = [dilindungi email]

Anda dapat membiarkan jalur sendmail dikomentari, itu akan tetap menggunakan default (di bawah opsi UNIX -t -i yang jika Anda cari sangat penting untuk disetel)...

Namun, sekarang tidak ada cara untuk mengubahnya, bahkan dengan argumen ke-5 dari fungsi mail(). -f penting, karena jika TIDAK disetel, akan disetel ke pengguna mana pun yang menjalankan skrip PHP, dan Anda mungkin tidak menginginkannya.

Selain itu, -f menyetel header Return-Path: yang digunakan sebagai alamat Bounce, jika terjadi kesalahan, sehingga Anda dapat memprosesnya. Anda tidak dapat menyetel Return-Path: di header mail() karena alasan tertentu... Anda bisa melakukannya sebelumnya. Sekarang Anda harus menggunakan opsi -f.

2 tahun lalu

Jika ada yang mendapatkan pesan kesalahan samar ini di log kesalahan PHP:
"sh: -t: perintah tidak ditemukan"
setelah upgrade dari PHP 5.4, ini mungkin solusi untuk Anda.

Saya memutakhirkan PHP dari 5.4 ke 5.6 dan semua fungsi mail() kami tiba-tiba rusak, tanpa ada pencatatan kesalahan yang berguna.

berkas ini; sekarang diabaikan jika Anda menggunakan ini_set() untuk menentukan jalur ke biner sendmail dengan cepat.

Jadi, tentukan saja "sendmail_path" di php.ini saja. Itu saja -- yang memperbaiki semua fungsi mail() untuk kami.

Semoga catatan kecil ini dapat menghemat waktu orang lain seperti yang saya habiskan untuk memecahkan masalah dan meneliti. Bersulang!

3 tahun yang lalu

Mengatur jalur pengembalian:

Header jalur kembali tidak berfungsi karena bukan bagian dari smtp.

Pada *nix -f dapat diatur pada perintah mail
kalau tidak
beberapa MTA menerima tajuk "Dari" bergaya mbox pada baris tajuk pertama
catatan: tidak ada titik dua setelah "From" , harus menjadi baris header pertama
atau Anda mungkin dapat mengonfigurasi ulang MTA Anda untuk menafsirkan header jalur kembali

F adalah metode yang paling dapat diandalkan tetapi ini mungkin berarti Anda tidak dapat mengatur opsi baris perintah lainnya karena masalah pelolosan shell.

perhatikan juga bahwa persyaratan pemformatan email berbeda antara windows dan yang lainnya. sendmail hanya mengharapkan \n akhiran baris

Setiap kali saya menyiapkan server web lokal, saya menemukan pertanyaan tentang rintisan untuk Sendmail.

Ada solusi hebat untuk Windows: sendmail palsu untuk windows(sendmail.exe) http://glob.com.au/sendmail/
Ada artikel di Habré tentang solusi ini: Email PHP untuk Windows http://habrahabr.ru/post/26518/
Solusi lain untuk Windows: Uji Alat Server Email http://www.toolheap.com/test-mail-server-tool/
Ada juga artikel untuk pengguna Linux: Rintisan Sendmail untuk Linux http://habrahabr.ru/post/49665/

Secara pribadi, saya lebih menyukai solusi dalam PHP murni, yang akan dibahas lebih lanjut.

Kelebihan:

  • Tidak ada layanan pihak ketiga
  • Solusi lintas platform untuk OS tempat PHP diinstal
  • Ukuran file rintisan minimum
  • Semua logika rintisan dapat diedit di PHP
  • Menyimpan pesan ke file

Dari kekurangannya:

  • Tidak ada penerusan ke kotak surat asli

Daftar argumen dan kemampuan rintisan:

  • --dir<Путь к папке> - Folder berkas
  • --mengajukan<имя файла> - Simpan setiap pesan dalam file bersama tertentu
  • --persiapkan- Tambahkan pesan baru ke awal file yang dibagikan
  • --membuka- Secara otomatis membuka file pesan di Notepad

Parameter untuk file PHP.INI:

;SMTP = localhost ;smtp_port = 25 ;sendmail_from = [dilindungi email] sendmail_path = "php.exe C:sendmail.php --dir C:mail --open"

Jika path ke php.exe ditentukan di PATH, maka Anda tidak perlu menentukannya di PHP.INI, jika tidak, disarankan untuk mengubah php.exe menjadi<Путь к папке с PHP>php.exe

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

Di Linux, Anda dapat langsung menentukan jalur ke file, jangan lupa membuatnya dapat diluncurkan terlebih dahulu: chmod 755 sendmail.php

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

Skrip sendmail.php itu sendiri:

#!/usr/local/bin/php

Saya akan senang jika ini bermanfaat bagi Anda.