PHP フォームから添付ファイル付きのメールを送信するにはどうすればよいですか?
4 に答える
他の人が回答で示唆しているように、既存のツールを使用するのがおそらく最善です。ただし、自分で作成したい場合、またはその方法を理解したい場合は、読み続けてください。
HTML
添付ファイルを送信するための HTML の要件は、実際には 2 つだけです。
- フォームには次の属性が必要です。
enctype="multipart/form-data"
- のようなフィールドが少なくとも 1 つ必要です
<input type="file" name="examplefile">
。これにより、ユーザーは添付するファイルを参照できます。
これらの両方がある場合、ブラウザはフォーム送信とともに添付ファイルをアップロードします。
補足: これらは一時ファイルとしてサーバーに保存されます。この例では、データを取得してメールで送信しますが、一時ファイルを永続的な場所に移動すると、ファイル アップロード フォームが作成されます。
MIME 電子メール形式
このチュートリアルは、PHP で MIME メール (HTML コンテンツ、プレーン テキスト バージョン、添付ファイルなどを含めることができる) を作成する方法を理解するのに最適です。出発点として使用しました。
基本的に、次の 3 つのことを行います。
- このメールには複数の種類のコンテンツが含まれることを前もって宣言してください
- 異なるセクションを区切るために使用するテキストの文字列を宣言します
- 各セクションを定義し、適切なコンテンツに貼り付けます。添付ファイルの場合は、タイプを指定して ASCII でエンコードする必要があります。
- 各セクションには、または
content-type
などがあります。詳細情報は、ここにあります。(私のサンプル スクリプトは、組み込みの PHP 関数を使用して、各ファイルからこの情報を取得します。)image/jpg
application/pdf.
- 各セクションには、または
PHP
フォームが送信されると、ブラウザーによってアップロードされたすべてのファイル (HTML セクションを参照) は、$_FILES
「HTTP POST メソッドを介して現在のスクリプトにアップロードされたアイテムの連想配列」を含む変数を介して利用可能になります。
のドキュメントは$_FILES
お粗末ですが、アップロード後に実行print_r($_FILES)
して、それがどのように機能するかを確認できます。次のような出力が得られます。
Array ( [examplefile] => Array ( [name] => your_filename.txt
[type] => text/plain [tmp_name] =>
C:\path\to\tmp\file\something.tmp [error] => 0 [size] => 200 ) )
を使用して、関連する一時ファイルのデータを取得できますfile_get_contents($_FILES['examplefile']['tmp_name'])
。
ファイルサイズの制限に関する補足事項
php.ini
には、添付ファイルのサイズを制限するいくつかの設定があります。詳細については、このディスカッションを参照してください。
PHP 関数の例
次の関数を作成しました。これをページに含めて、フォームで送信された添付ファイルを収集するために使用できます。自由に使用したり、ニーズに合わせて調整したりしてください。
添付ファイルの合計制限は任意ですが、大量のファイルがあるとmail()
スクリプトが停止したり、送信または受信の電子メール サーバーによって拒否されたりする可能性があります。独自のテストを行います。
(注: PHP の関数は、メールの送信方法を知るためのmail()
情報に依存します。)php.ini
function sendWithAttachments($to, $subject, $htmlMessage){
$maxTotalAttachments=2097152; //Maximum of 2 MB total attachments, in bytes
$boundary_text = "anyRandomStringOfCharactersThatIsUnlikelyToAppearInEmail";
$boundary = "--".$boundary_text."\r\n";
$boundary_last = "--".$boundary_text."--\r\n";
//Build up the list of attachments,
//getting a total size and adding boundaries as needed
$emailAttachments = "";
$totalAttachmentSize = 0;
foreach ($_FILES as $file) {
//In case some file inputs are left blank - ignore them
if ($file['error'] == 0 && $file['size'] > 0){
$fileContents = file_get_contents($file['tmp_name']);
$totalAttachmentSize += $file['size']; //size in bytes
$emailAttachments .= "Content-Type: "
.$file['type'] . "; name=\"" . basename($file['name']) . "\"\r\n"
."Content-Transfer-Encoding: base64\r\n"
."Content-disposition: attachment; filename=\""
.basename($file['name']) . "\"\r\n"
."\r\n"
//Convert the file's binary info into ASCII characters
.chunk_split(base64_encode($fileContents))
.$boundary;
}
}
//Now all the attachment data is ready to insert into the email body.
//If the file was too big for PHP, it may show as having 0 size
if ($totalAttachmentSize == 0) {
echo "Message not sent. Either no file was attached, or it was bigger than PHP is configured to accept.";
}
//Now make sure it doesn't exceed this function's specified limit:
else if ($totalAttachmentSize>$maxTotalAttachments) {
echo "Message not sent. Total attachments can't exceed " . $maxTotalAttachments . " bytes.";
}
//Everything is OK - let's build up the email
else {
$headers = "From: yourserver@example.com\r\n";
$headers .= "MIME-Version: 1.0\r\n"
."Content-Type: multipart/mixed; boundary=\"$boundary_text\"" . "\r\n";
$body .="If you can see this, your email client "
."doesn't accept MIME types!\r\n"
.$boundary;
//Insert the attachment information we built up above.
//Each of those attachments ends in a regular boundary string
$body .= $emailAttachments;
$body .= "Content-Type: text/html; charset=\"iso-8859-1\"\r\n"
."Content-Transfer-Encoding: 7bit\r\n\r\n"
//Inert the HTML message body you passed into this function
.$htmlMessage . "\r\n"
//This section ends in a terminating boundary string - meaning
//"that was the last section, we're done"
.$boundary_last;
if(mail($to, $subject, $body, $headers))
{
echo "<h2>Thanks!</h2>Form submitted to " . $to . "<br />";
} else {
echo 'Error - mail not sent.';
}
}
}
ここで何が起こっているかを見たい場合は、呼び出しをコメントアウトして、mail()
代わりに出力を画面にエコーさせます。
素敵なチュートリアルはこちら
コード
<?php
//define the receiver of the email
$to = 'youraddress@example.com';
//define the subject of the email
$subject = 'Test email with attachment';
//create a boundary string. It must be unique
//so we use the MD5 algorithm to generate a random hash
$random_hash = md5(date('r', time()));
//define the headers we want passed. Note that they are separated with \r\n
$headers = "From: webmaster@example.com\r\nReply-To: webmaster@example.com";
//add boundary string and mime type specification
$headers .= "\r\nContent-Type: multipart/mixed; boundary=\"PHP-mixed-".$random_hash."\"";
//read the atachment file contents into a string,
//encode it with MIME base64,
//and split it into smaller chunks
$attachment = chunk_split(base64_encode(file_get_contents('attachment.zip')));
//define the body of the message.
ob_start(); //Turn on output buffering
?>
--PHP-mixed-<?php echo $random_hash; ?>
Content-Type: multipart/alternative; boundary="PHP-alt-<?php echo $random_hash; ?>"
--PHP-alt-<?php echo $random_hash; ?>
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
Hello World!!!
This is simple text email message.
--PHP-alt-<?php echo $random_hash; ?>
Content-Type: text/html; charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
<h2>Hello World!</h2>
<p>This is something with <b>HTML</b> formatting.</p>
--PHP-alt-<?php echo $random_hash; ?>--
--PHP-mixed-<?php echo $random_hash; ?>
Content-Type: application/zip; name="attachment.zip"
Content-Transfer-Encoding: base64
Content-Disposition: attachment
<?php echo $attachment; ?>
--PHP-mixed-<?php echo $random_hash; ?>--
<?php
//copy current buffer contents into $message variable and delete current output buffer
$message = ob_get_clean();
//send the email
$mail_sent = @mail( $to, $subject, $message, $headers );
//if the message is sent successfully print "Mail sent". Otherwise print "Mail failed"
echo $mail_sent ? "Mail sent" : "Mail failed";
?>
実際の電子メールを送信するには、PHPMailer ライブラリを使用することをお勧めします。これにより、すべてがはるかに簡単になります。
SwiftMailerをチェックしてみてください。これに関する素晴らしいチュートリアルがあります。