PHPのお勉強!

PHP TOP

mail

(PHP 4, PHP 5, PHP 7, PHP 8)

mailメールを送信する

説明

mail(
    string $to,
    string $subject,
    string $message,
    array|string $additional_headers = [],
    string $additional_params = ""
): bool

メールを送信します。

パラメータ

to

メールの受信者。

» RFC 2822 を満たす書式でなければ なりません。例えば以下のようなものです。

  • user@example.com
  • user@example.com, anotheruser@example.com
  • User
  • User , Another User

subject

送信するメールの表題。

警告

表題は » RFC 2047 を満たすものでなければなりません。

message

送信するメッセージ。

改行コードは CRLF (\r\n) となります。各行の長さは 70 文字を超えては いけません。

警告

(Windows のみ)PHP が SMTP サーバーと直接通信をする際、ピリオドから 始まる行は無視されます。これを防ぐには、行頭のピリオドを ピリオド 2 つに置き換えてください。

<?php
$text
= str_replace("\n.", "\n..", $text);
?>

additional_headers(オプション)

メールヘッダの最後に挿入される String または array

通常、これは追加のヘッダ(From、Cc、Bcc)のために用いられます。 複数のヘッダを追加する場合は CRLF(\r\n)で区切ります。 外部からのデータを用いてヘッダを組み立てる際には、想定外のヘッダが注入されることを防ぐための処理が必要です。

array が渡されると、キーがヘッダの名前となり、 値がそれぞれのヘッダの値になります。

注意:

メールを送信する際には、必ず From ヘッダが含まれていなければなりません。 additional_headers パラメータで指定するか、 あるいは php.ini にデフォルト値を指定します。

指定しなかった場合は、以下のようなエラーメッセージが返ります Warning: mail(): "sendmail_from" not set in php.ini or custom "From:" header missing 。 Windows では、SMTP経由で直接メールを送信する際は、 From ヘッダを設定すると Return-Path も設定されます。

注意:

メッセージが受信されなかった場合には、LF(\n)のみを使ってみてください。 Unix の MTA の中には、自動的に LF を CRLF に変換してしまう もの (有名なところでは、» qmail など) があります(もし CRLF を利用していた場合、CR が重複してしまいます)。 ただし、これは最後の手段です。というのも、これは » RFC 2822 に違反しているからです。

additional_params(オプション)

パラメータ additional_params は、 追加のフラグをコマンドラインオプションとしてメール送信プログラムに渡す際に使用可能です。 メール送信プログラムは、設定オプション sendmail_path により設定されます。例えば、 sendmail を使用する際に -f オプションを使って エンベロープの sender アドレスを設定する際に使用できます。

このパラメータはコマンドの実行を防止するために内部的に escapeshellcmd() によってエスケープされます。 escapeshellcmd() はコマンドの実行を防止しますが、 別のパラメータを追加することは許してしまいます。セキュリティ上の理由から、 シェルコマンドへの望ましくないパラメータの追加を避けるために、 ユーザーはこのパラメータを適切に処理することが推奨されます。

escapeshellcmd() が自動的に適用されるため、 インターネット RFC でメールアドレスとして許可さているいくつかの文字を使用することができません。 mail() はそうした文字を許可しないため、プログラム中でそうした文字の使用が必須である場合、 メール送信の代替手段(フレームワークやライブラリの使用など)が推奨されます。

この方法でエンベロープの sender ヘッダ(-f)を設定する際は、 'X-Warning' ヘッダが付加されないように Web サーバーの実行ユーザーを sendmail 設定に追加しておく必要があるかもしれません。 sendmail を利用している場合、これは /etc/mail/trusted-users で設定します。

戻り値

メール送信が受け入れられた場合に true 、それ以外の場合に false を返します。

メールの配送が受け入れられたかどうかが基準であることに注意しましょう。 メールが実際にあて先に届いたかどうかでは「ありません」。

変更履歴

バージョン 説明
7.2.0 additional_headers パラメータは、 array も受け入れるようになりました。

例1 メールを送信する

mail() を用いて単純なメールを送信する。

<?php
// 本文
$message = "Line 1\r\nLine 2\r\nLine 3";

// 1 行が 70 文字を超える場合のため、wordwrap() を用いる
$message = wordwrap($message, 70, "\r\n");

// 送信する
mail('caffeinated@example.com', 'My Subject', $message);
?>

例2 追加ヘッダを付加してメールを送信する

基本ヘッダに加え、MUA に From および Reply-To アドレスを通知する。

<?php
$to
= 'nobody@example.com';
$subject = 'the subject';
$message = 'hello';
$headers = 'From: webmaster@example.com' . "\r\n" .
'Reply-To: webmaster@example.com' . "\r\n" .
'X-Mailer: PHP/' . phpversion();

mail($to, $subject, $message, $headers);
?>

例3 追加のヘッダを array で指定してメールを送信する

この例は、すぐ上の例と同じメールを送信します。 しかし、追加のヘッダを配列で渡しています (PHP 7.2.0 以降で利用可能)

<?php
$to
= 'nobody@example.com';
$subject = 'the subject';
$message = 'hello';
$headers = array(
'From' => 'webmaster@example.com',
'Reply-To' => 'webmaster@example.com',
'X-Mailer' => 'PHP/' . phpversion()
);

mail($to, $subject, $message, $headers);
?>

例4 追加のコマンドラインパラメータを指定してメールを送信する

sendmail_path を用いてメールを送信する際に利用する 追加パラメータとして、additional_params が用いられます。

<?php
mail
('nobody@example.com', 'the subject', 'the message', null,
'-fwebmaster@example.com');
?>

例5 HTML メールを送信する

mail() を用いて HTML メールを送信することも可能です。

<?php
// 複数の受信者を指定
$to = 'johny@example.com, sally@example.com'; // カンマに注意

// 表題
$subject = 'Birthday Reminders for August';

// 本文
$message = '
<html>
<head>
<title>Birthday Reminders for August</title>
</head>
<body>
<p>Here are the birthdays upcoming in August!</p>
<table>
<tr>
<th>Person</th><th>Day</th><th>Month</th><th>Year</th>
</tr>
<tr>
<td>Johny</td><td>10th</td><td>August</td><td>1970</td>
</tr>
<tr>
<td>Sally</td><td>17th</td><td>August</td><td>1973</td>
</tr>
</table>
</body>
</html>
'
;

// HTML メールを送信するには Content-type ヘッダが必須
$headers[] = 'MIME-Version: 1.0';
$headers[] = 'Content-type: text/html; charset=iso-8859-1';

// 追加のヘッダ
$headers[] = 'To: Mary <mary@example.com>, Kelly <kelly@example.com>';
$headers[] = 'From: Birthday Reminder <birthday@example.com>';
$headers[] = 'Cc: birthdayarchive@example.com';
$headers[] = 'Bcc: birthdaycheck@example.com';

// 送信する
mail($to, $subject, $message, implode("\r\n", $headers));
?>

注意:

HTML などの複雑な形式のメールを送信する場合は、PEAR パッケージ » PEAR::Mail_Mime を利用することを推奨します。

注意

注意:

Windows 環境での mail() のSMTP実装は、sendmail の実装とは 多くの点で違います。 第一に、メッセージの生成にローカルのバイナリは使用せず、 ソケットを通じて直接操作するだけです。 これは MTA がネットワークソケットを listen している 必要があるということを意味します(ローカルホスト、リモートマシン どちらでもかまいません)。

第二に、 From:Cc:Bcc:Date: のようなカスタムヘッダは MTA ではなく PHP によってパースされます。

そのため、to 引数には "Something <someone@example.com>" 形式の メールアドレスを与えることはできません。 MTA と通信する際に mail コマンドはこれを適切にパースできません。

注意:

mail() 関数は、大量のメールをループ内で送信するには 向いていないことに注意しましょう。この関数は 1 通のメールを送信するたびに SMTP ソケットをいったん閉じて開きなおします。これは非効率的です。

大量のメールを送信する場合は、 » PEAR::Mail および » PEAR::Mail_Queue パッケージを参照ください。

注意:

以下の RFC も有用です。 » RFC 1896» RFC 2045» RFC 2046» RFC 2047» RFC 2048» RFC 2049 および » RFC 2822

参考

add a note

User Contributed Notes 18 notes

up
35
Anonymous
8 years ago
Security advice: Although it is not documented, for the parameters $to and $subject the mail() function changes at least \r and \n to space. So these parameters are safe against injection of additional headers. But you might want to check $to for commas as these separate multiple addresses and you might not want to send to more than one recipient.

The crucial part is the $additional_headers parameter. This parameter can't be cleaned by the mail() function. So it is up to you to prevent unwanted \r or \n to be inserted into the values you put in there. Otherwise you just created a potential spam distributor.
up
27
php at simoneast dot net
7 years ago
Often it's helpful to find the exact error message that is triggered by the mail() function. While the function doesn't provide an error directly, you can use error_get_last() when mail() returns false.

<?php
$success
= mail('example@example.com', 'My Subject', $message);
if (!
$success) {
$errorMessage = error_get_last()['message'];
}
?>

(Tested successfully on Windows which uses SMTP by default, but sendmail on Linux/OSX may not provide the same level of detail.)

Thanks to https://stackoverflow.com/a/20203870/195835
up
13
priyanshkala3 at gmail dot com
1 year ago
Sending mail using XAMPP server

I encountered numerous issues while attempting to send emails using the XAMPP server. However, I eventually found the correct method to accomplish it.

Configuring PHP's mail functionality to work with Gmail's SMTP server involves editing the `php.ini` and `sendmail.ini` configuration files. Below are the formal steps for setting up PHP to send emails through Gmail's SMTP server using XAMPP:

Configuring php.ini:

1. Open `php.ini` in an editor:
Open the `php.ini` configuration file in your preferred text editor.

2. Locate the mail function:
Use the search function (Ctrl + F) to find the section related to the mail function within the `php.ini` file.

3. Update mail function settings:
Copy and paste the following configuration parameters into the mail function section. Comment out or disable all other settings related to mail.

php.ini code to be edited:

SMTP=smtp.gmail.com
smtp_port=587
sendmail_from = yourmail@gmail.com
sendmail_path = write_sendmail.exe_path


4. Save the changes:
Save the `php.ini` file after applying the modifications.

Configuring sendmail.ini (in XAMPP folder):

1. Open `sendmail.ini` in XAMPP folder:
Locate and open the `sendmail.ini` configuration file within the XAMPP directory.

2. Adjust SMTP settings:
Insert the following content into the `sendmail.ini` file, marking other configurations as comments:

sendmail.ini code :

smtp_server=smtp.gmail.com
smtp_port=587
error_logfile=error.log
debug_logfile=debug.log
auth_username=yourmail@gmail.com
auth_password=app_password_after_enabling_two_factor_authentication_for_your_mail_id
force_sender=priyansh.kala.4@gmail.com


3. Save the changes:
Save the `sendmail.ini` file after inserting the specified configurations.

These steps configure PHP to utilize Gmail's SMTP server for sending emails. Ensure that the modifications are saved and that the necessary XAMPP services are restarted for the changes to take effect.

Please note that using hardcoded passwords in configuration files poses a security risk. Storing passwords directly in plain text files should be avoided in production environments. Consider using environment variables or secure credential management systems for better security practices.

Code for sending mail-:

<?php
$subject
= "Mail for checking";
$msg = "Hey! Let us play with PHP.";
$receiver = "reciever@gmail.com";
mail($receiver, $subject, $msg);
?>
up
23
Anonymous
5 years ago
If you notice wrong displayed characters in the email it's because you need to properly set the Content-Type and the Charset in the headers of the email:

<?php
$headers
= 'Content-Type: text/plain; charset=utf-8' . "\r\n";
?>

Mostly, UTF-8 is your best choice.

You can set custom headers with the fourth parameter of the mail() function.

To make the whole thing waterproof, add the following header too:

<?php
$headers
.= 'Content-Transfer-Encoding: base64' . "\r\n";
?>

Now you can use the combination of UTF-8 and Base64 to properly encode the subject line and the recipient name like this:

<?php
$subject
= '=?UTF-8?B?' . base64_encode('Test email with German Umlauts öäüß') . '?=';
$recipient = '=?UTF-8?B?' . base64_encode('Margret Müller') . '?= <recipient@domain.com>';
?>

And don't forget to Base64 encode the email message too:

<?php
$message
= base64_encode('This email contains German Umlauts öäüß.');
?>

All references are taken from:
https://dev.to/lutvit/how-to-make-the-php-mail-function-awesome-3cii
up
11
charles dot fisher at arconic dot com
7 years ago
I migrated an application to a platform without a local transport agent (MTA). I did not want to configure an MTA, so I wrote this xxmail function to replace mail() with calls to a remote SMTP server. Hopefully it is of some use.

function xxmail($to, $subject, $body, $headers)
{
$smtp = stream_socket_client('tcp://smtp.yourmail.com:25', $eno, $estr, 30);

$B = 8192;
$c = "\r\n";
$s = 'myapp@someserver.com';

fwrite($smtp, 'helo ' . $_ENV['HOSTNAME'] . $c);
$junk = fgets($smtp, $B);

// Envelope
fwrite($smtp, 'mail from: ' . $s . $c);
$junk = fgets($smtp, $B);
fwrite($smtp, 'rcpt to: ' . $to . $c);
$junk = fgets($smtp, $B);
fwrite($smtp, 'data' . $c);
$junk = fgets($smtp, $B);

// Header
fwrite($smtp, 'To: ' . $to . $c);
if(strlen($subject)) fwrite($smtp, 'Subject: ' . $subject . $c);
if(strlen($headers)) fwrite($smtp, $headers); // Must be \r\n (delimited)
fwrite($smtp, $headers . $c);

// Body
if(strlen($body)) fwrite($smtp, $body . $c);
fwrite($smtp, $c . '.' . $c);
$junk = fgets($smtp, $B);

// Close
fwrite($smtp, 'quit' . $c);
$junk = fgets($smtp, $B);
fclose($smtp);
}