ส่งไฟล์แนบด้วย PHP Mail () หรือไม่


224

ฉันจำเป็นต้องส่งไฟล์ PDF พร้อมเมลเป็นไปได้ไหม

$to = "xxx";
$subject = "Subject" ;
$message = 'Example message with <b>html</b>';
$headers  = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
$headers .= 'From: xxx <xxx>' . "\r\n";
mail($to,$subject,$message,$headers);

ฉันพลาดอะไรไป

php 

16
ในการส่งไฟล์แนบพร้อมmail()ฟังก์ชั่นนั้นยากกว่าที่คุณคาดไว้ให้ลองใช้PHPMailer
Mihai Iorga

1
หรือคุณเพียงแค่เชื่อมโยงกับมัน?

@mihai lorga นั่นไม่จำเป็นต้องติดตั้งฝั่งเซิร์ฟเวอร์? หากเป็นไปได้โดยไม่มีส่วนขยายหรือปลั๊กอินฉันต้องรู้วิธี

ค้นหา Google อย่างรวดเร็ว - webcheatsheet.com/php/send_email_text_html_attachment.php
ทำเครื่องหมาย

2
@ChristianNikkanen เป็นเพียงสคริปต์ที่ดี แต่ยังมีคุณสมบัติมากมายที่ยากที่จะทำให้สำเร็จ ทำไมต้องคิดค้นล้อใหม่ ไม่ใช้ปลั๊กอินเพิ่มเติมใด ๆ
Mihai Iorga

คำตอบ:


310

ฉันเห็นด้วยกับ @MihaiIorga ในความคิดเห็น - ใช้สคริปต์ PHPMailer คุณดูเหมือนคุณจะปฏิเสธเพราะคุณต้องการตัวเลือกที่ง่ายขึ้น เชื่อใจฉัน PHPMailer เป็นตัวเลือกที่ง่ายกว่าด้วยอัตรากำไรที่สูงมากเมื่อเทียบกับการพยายามทำด้วยตัวเองด้วยmail()ฟังก์ชั่นการใช้งานของ PHP mail()ฟังก์ชั่นของ PHP นั้นไม่ค่อยดีนัก

วิธีใช้ PHPMailer:

  • ดาวน์โหลดสคริปต์ PHPMailer ได้จากที่นี่: http://github.com/PHPMailer/PHPMailer
  • แตกไฟล์เก็บถาวรและคัดลอกโฟลเดอร์ของสคริปต์ไปยังตำแหน่งที่สะดวกในโครงการของคุณ
  • รวมไฟล์สคริปต์หลัก - require_once('path/to/file/class.phpmailer.php');

ตอนนี้การส่งอีเมลพร้อมไฟล์แนบเริ่มจากยากที่จะเมามันจนง่ายอย่างไม่น่าเชื่อ:

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

$email = new PHPMailer();
$email->SetFrom('you@example.com', 'Your Name'); //Name is optional
$email->Subject   = 'Message Subject';
$email->Body      = $bodytext;
$email->AddAddress( 'destinationaddress@example.com' );

$file_to_attach = 'PATH_OF_YOUR_FILE_HERE';

$email->AddAttachment( $file_to_attach , 'NameOfFile.pdf' );

return $email->Send();

เป็นเพียงแค่บรรทัดเดียว$email->AddAttachment();- คุณไม่สามารถขออะไรได้อีก

ถ้าคุณทำมันด้วยmail()ฟังก์ชั่นของ PHP คุณจะต้องเขียนสแต็กของรหัสและคุณอาจมีข้อผิดพลาดมากมายในการค้นหาข้อบกพร่อง


1
ใช่ว่าง่าย จุดรวมของ phpMailer คือการทำสิ่งที่ซับซ้อนดังนั้นคุณไม่จำเป็นต้อง นั่นเป็นเหตุผลที่มันซับซ้อนในการอ่าน แม้สำหรับการส่งอีเมลแบบข้อความเท่านั้นฉันชอบ phpMailer ไปmail()แต่สำหรับการทำงานกับไฟล์แนบมันเป็นเกมง่ายๆ
SDC

4
ฉันเหมือนกัน - ต้องการใช้เมล () เพียงเพราะฉันมีอยู่ในโค้ดของฉันแล้ว PHPMAILER ใช้เวลาน้อยกว่า 5 นาทีในการรับไฟล์แนบ!
James Wilson

109
ฉันพบคำถามนี้เพื่อค้นหาคำตอบวิธีการใช้mail()ฟังก์ชั่นเพื่อเพิ่มไฟล์แนบ คำตอบนี้ไม่ได้ช่วยให้ฉันทำอย่างนั้น
Cypher

19
นี่ไม่ใช่คำตอบสำหรับคำถาม วิธีส่งไฟล์แนบกับ PHPMailer ไม่ใช่วิธีส่งไฟล์แนบด้วยเมลของ PHP () ซึ่งเป็นสิ่งที่ถูกถาม
Toby

4
คำตอบนี้ยังเพิกเฉยต่อใบอนุญาตที่ใช้โดยโครงการ ด้วยการใช้ PHPMailer คุณต้องแน่ใจว่าคุณได้แยกแพ็คเกจออกจากแหล่งของคุณเพื่อป้องกันปัญหาเกี่ยวกับลิขสิทธิ์ LGPL
Axle

190

คุณสามารถลองใช้รหัสต่อไปนี้:

    $filename = 'myfile';
    $path = 'your path goes here';
    $file = $path . "/" . $filename;

    $mailto = 'mail@mail.com';
    $subject = 'Subject';
    $message = 'My message';

    $content = file_get_contents($file);
    $content = chunk_split(base64_encode($content));

    // a random hash will be necessary to send mixed content
    $separator = md5(time());

    // carriage return type (RFC)
    $eol = "\r\n";

    // main header (multipart mandatory)
    $headers = "From: name <test@test.com>" . $eol;
    $headers .= "MIME-Version: 1.0" . $eol;
    $headers .= "Content-Type: multipart/mixed; boundary=\"" . $separator . "\"" . $eol;
    $headers .= "Content-Transfer-Encoding: 7bit" . $eol;
    $headers .= "This is a MIME encoded message." . $eol;

    // message
    $body = "--" . $separator . $eol;
    $body .= "Content-Type: text/plain; charset=\"iso-8859-1\"" . $eol;
    $body .= "Content-Transfer-Encoding: 8bit" . $eol;
    $body .= $message . $eol;

    // attachment
    $body .= "--" . $separator . $eol;
    $body .= "Content-Type: application/octet-stream; name=\"" . $filename . "\"" . $eol;
    $body .= "Content-Transfer-Encoding: base64" . $eol;
    $body .= "Content-Disposition: attachment" . $eol;
    $body .= $content . $eol;
    $body .= "--" . $separator . "--";

    //SEND Mail
    if (mail($mailto, $subject, $body, $headers)) {
        echo "mail send ... OK"; // or use booleans here
    } else {
        echo "mail send ... ERROR!";
        print_r( error_get_last() );
    }

แก้ไข 14 มิถุนายน - 2018

เพื่อให้อ่านได้ง่ายขึ้นในการใช้งานของผู้ให้บริการอีเมล

$body .= $eol . $message . $eol . $eol; และ $body .= $eol . $content . $eol . $eol;


$ uid ดูเหมือนจะไม่ได้ใช้
Edd

ใครบางคนชี้ให้เห็นในคำตอบว่าควรจะมีการแสดงความคิดเห็นว่าตั้งแต่รหัสของ OP กล่าว'Example message with <b>html</b>'แล้วประเภทเนื้อหาที่ควรจะเป็นมากกว่าtext/html text/plainฉันโพสต์ความคิดเห็นในนามของเขาเนื่องจากเขามีตัวแทนไม่เพียงพอที่จะโพสต์ความคิดเห็นและฉันตั้งค่าสถานะคำตอบสำหรับการลบ
Adi Inbar

ในรหัสนี้คุณต้องกำหนด $ path และ $ filename หรือไม่ และมันจะคล้ายกับ $ filename = $ _FILES ['userfile'] ['tmp_name']; ?
ผิดปกติ

ทำไมคุณประกาศ$fileหลังจากที่อ้างอิงไว้ใน$filename?
Kolob Canyon

2
จากเอกสารของ PHPMailer ... "การจัดรูปแบบอีเมลอย่างถูกต้องเป็นเรื่องยากอย่างน่าประหลาดใจมี RFC ที่ทับซ้อนกันมากมายต้องการการยึดติดอย่างแน่นหนากับกฎการจัดรูปแบบและการเข้ารหัสที่ซับซ้อนอย่างน่ากลัว - รหัสส่วนใหญ่ที่คุณจะพบออนไลน์ ผิดธรรมดา! " ...มันเป็นความจริง! ฉันใช้บางอย่างเช่นคำตอบนี้เพื่อส่งเมลพร้อมไฟล์แนบและใช้งานได้! พบเพียงไม่กี่วันหลังจากนั้นในขณะที่ Gmail แสดงสิ่งที่แนบมาได้ดีผู้ให้บริการรายอื่นจะแสดงเนื้อหาฐาน 64 แบบอินไลน์โดยตรงในจดหมาย
Aaron Cicali

134

สำหรับการอัพเดทความปลอดภัย PHP 5.5.27

$file = $path.$filename;
$content = file_get_contents( $file);
$content = chunk_split(base64_encode($content));
$uid = md5(uniqid(time()));
$name = basename($file);

// header
$header = "From: ".$from_name." <".$from_mail.">\r\n";
$header .= "Reply-To: ".$replyto."\r\n";
$header .= "MIME-Version: 1.0\r\n";
$header .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"\r\n\r\n";

// message & attachment
$nmessage = "--".$uid."\r\n";
$nmessage .= "Content-type:text/plain; charset=iso-8859-1\r\n";
$nmessage .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
$nmessage .= $message."\r\n\r\n";
$nmessage .= "--".$uid."\r\n";
$nmessage .= "Content-Type: application/octet-stream; name=\"".$filename."\"\r\n";
$nmessage .= "Content-Transfer-Encoding: base64\r\n";
$nmessage .= "Content-Disposition: attachment; filename=\"".$filename."\"\r\n\r\n";
$nmessage .= $content."\r\n\r\n";
$nmessage .= "--".$uid."--";

if (mail($mailto, $subject, $nmessage, $header)) {
    return true; // Or do something here
} else {
  return false;
}

คุณไม่ได้กำหนดชื่อไฟล์ $ มันควรจะเป็นอะไร ไฟล์พา ธ ?
Jon

3
@ จอน $ filename เป็นชื่อจริงของไฟล์ของคุณและ $ path เป็นพา ธ ไฟล์จริงโดยไม่มีชื่อไฟล์ ฉันคิดว่าตัวแปรมีความหมายเพียงพอที่จะประกาศและจัดระเบียบพวกเขา
Simon Mokhele

มันหมายถึงการอยู่ในฟังก์ชั่นถ้าคุณไม่ต้องการกำหนดฟังก์ชั่น mail_attachment ($ filename, $ path, $ pathto, $ from_mail, $ from_mail, $ from_name, $ replyto, $ subject, $ message)
Jon

3
หมายเหตุสำหรับผู้ที่ส่งไฟล์แนบหลายรายการ - แยกส่วน MIME ด้วย$nmessage .= "--".$uid."\r\n";และหลังจากส่วน MIME สุดท้ายให้ใช้$nmessage .= "--".$uid."--";(ดังที่แสดงด้านบน)
rinogo

2
ในที่สุดนี้ก็ทำงานหลังจากปวดหัวของการพยายามรับสิ่ง phpmailer โง่ทำงาน
E.Arrowood

22

Swiftmailerเป็นสคริปต์ที่ใช้งานง่ายอีกตัวหนึ่งที่ป้องกันการฉีดอีเมล์โดยอัตโนมัติและทำให้ไฟล์แนบเป็นเรื่องง่าย ฉันไม่สนับสนุนการใช้mail()ฟังก์ชันในตัวของ PHP อย่างยิ่ง

ใช้:

  • ดาวน์โหลดSwiftmailerและวางlibโฟลเดอร์ในโครงการของคุณ
  • รวมไฟล์หลักโดยใช้ require_once 'lib/swift_required.php';

ตอนนี้เพิ่มรหัสเมื่อคุณต้องการส่งจดหมาย:

// Create the message
$message = Swift_Message::newInstance()
    ->setSubject('Your subject')
    ->setFrom(array('webmaster@mysite.com' => 'Web Master'))
    ->setTo(array('receiver@example.com'))
    ->setBody('Here is the message itself')
    ->attach(Swift_Attachment::fromPath('myPDF.pdf'));

//send the message          
$mailer->send($message);

ข้อมูลเพิ่มเติมและตัวเลือกที่สามารถพบได้ในSwiftmailer เอกสาร


6
ทำให้คุณเสนอให้ dwonload ห้องสมุดบุคคลที่สามฉันเดา
vladkras

PHPMailer ไม่ใช่บุคคลที่สามหรือไม่ หรือหมายถึง @MatthewJohnson ทำหรือเป็นส่วนหนึ่งของผู้ดูแลระบบของ swiftmailer หรือไม่ ทั้งสองวิธีตราบใดที่วิธีการแก้ปัญหาเป็นสิ่งที่ดีและมีประสิทธิภาพ downvote จะไม่เหมาะสม ...
Xsmael

1
@ Xsmael, PHPMailer เป็นบุคคลที่สามแน่นอน :) ฉันไม่เห็นด้วยกับ downvotes เช่น (อย่างน้อยในเวลา) วิธีการแก้ปัญหาทำงาน อย่างไรก็ตามผู้คนสามารถลงคะแนนได้อย่างไรก็ตามพวกเขาต้องการและ upvotes มากกว่าคัดค้านการลง
Matthew Johnson

17

ในการส่งอีเมลพร้อมไฟล์แนบเราจำเป็นต้องใช้ประเภท MIME แบบหลายส่วน / แบบผสมที่ระบุว่าประเภทแบบผสมจะรวมอยู่ในอีเมล ยิ่งไปกว่านั้นเราต้องการใช้ประเภท MIME หลายส่วน / ทางเลือกเพื่อส่งทั้งข้อความธรรมดาและ HTML ของอีเมลดูตัวอย่าง:

<?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"; 
?>

อย่างที่คุณเห็นการส่งอีเมลพร้อมไฟล์แนบนั้นทำได้ง่าย ในตัวอย่างก่อนหน้านี้เรามีประเภท MIME หลายส่วน / ผสมและภายในนั้นเรามีประเภท MIME หลายส่วน / ทางเลือกที่ระบุอีเมลสองรุ่น ในการรวมสิ่งที่แนบมากับข้อความของเราเราอ่านข้อมูลจากไฟล์ที่ระบุเป็นสตริงเข้ารหัสด้วย base64 แยกเป็นชิ้นเล็ก ๆ เพื่อให้แน่ใจว่าตรงกับข้อกำหนด MIME จากนั้นรวมเป็นสิ่งที่แนบ

ที่นำมาจากที่นี่


15
คัดลอก / วางเนื้อหาในลิงค์ที่ฉันเพิ่มไว้ในความคิดเห็น OP
ทำเครื่องหมาย

ตัวอย่างที่ดีแม้ว่าฉันจะต้องให้การขึ้นบรรทัดใหม่พิเศษหลังจากสตริงขอบเขตเพื่อให้มันทำงาน ฉันเดาว่ามันเกี่ยวข้องกับการสิ้นสุดบรรทัดของไฟล์ php ตัวแก้ไขของฉันใช้ค่าเริ่มต้นเป็น LF แต่ฉันคิดว่ามาตรฐานคาดว่าการรับคืนค่าตอบแทนเช่นกัน (CRLF)
Ogier Schelvis

9

มันใช้งานได้สำหรับฉัน นอกจากนี้ยังแนบหลายไฟล์แนบด้วย อย่างง่ายดาย

<?php

if ($_POST && isset($_FILES['file'])) {
    $recipient_email = "recipient@yourmail.com"; //recepient
    $from_email = "info@your_domain.com"; //from email using site domain.
    $subject = "Attachment email from your website!"; //email subject line

    $sender_name = filter_var($_POST["s_name"], FILTER_SANITIZE_STRING); //capture sender name
    $sender_email = filter_var($_POST["s_email"], FILTER_SANITIZE_STRING); //capture sender email
    $sender_message = filter_var($_POST["s_message"], FILTER_SANITIZE_STRING); //capture message
    $attachments = $_FILES['file'];

    //php validation
    if (strlen($sender_name) < 4) {
        die('Name is too short or empty');
    }
    if (!filter_var($sender_email, FILTER_VALIDATE_EMAIL)) {
        die('Invalid email');
    }
    if (strlen($sender_message) < 4) {
        die('Too short message! Please enter something');
    }

    $file_count = count($attachments['name']); //count total files attached
    $boundary = md5("specialToken$4332"); // boundary token to be used

    if ($file_count > 0) { //if attachment exists
        //header
        $headers = "MIME-Version: 1.0\r\n";
        $headers .= "From:" . $from_email . "\r\n";
        $headers .= "Reply-To: " . $sender_email . "" . "\r\n";
        $headers .= "Content-Type: multipart/mixed; boundary = $boundary\r\n\r\n";

        //message text
        $body = "--$boundary\r\n";
        $body .= "Content-Type: text/plain; charset=ISO-8859-1\r\n";
        $body .= "Content-Transfer-Encoding: base64\r\n\r\n";
        $body .= chunk_split(base64_encode($sender_message));

        //attachments
        for ($x = 0; $x < $file_count; $x++) {
            if (!empty($attachments['name'][$x])) {

                if ($attachments['error'][$x] > 0) { //exit script and output error if we encounter any
                    $mymsg = array(
                        1 => "The uploaded file exceeds the upload_max_filesize directive in php.ini",
                        2 => "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form",
                        3 => "The uploaded file was only partially uploaded",
                        4 => "No file was uploaded",
                        6 => "Missing a temporary folder");
                    die($mymsg[$attachments['error'][$x]]);
                }

                //get file info
                $file_name = $attachments['name'][$x];
                $file_size = $attachments['size'][$x];
                $file_type = $attachments['type'][$x];

                //read file 
                $handle = fopen($attachments['tmp_name'][$x], "r");
                $content = fread($handle, $file_size);
                fclose($handle);
                $encoded_content = chunk_split(base64_encode($content)); //split into smaller chunks (RFC 2045)

                $body .= "--$boundary\r\n";
                $body .= "Content-Type: $file_type; name=" . $file_name . "\r\n";
                $body .= "Content-Disposition: attachment; filename=" . $file_name . "\r\n";
                $body .= "Content-Transfer-Encoding: base64\r\n";
                $body .= "X-Attachment-Id: " . rand(1000, 99999) . "\r\n\r\n";
                $body .= $encoded_content;
            }
        }
    } else { //send plain email otherwise
        $headers = "From:" . $from_email . "\r\n" .
                "Reply-To: " . $sender_email . "\n" .
                "X-Mailer: PHP/" . phpversion();
        $body = $sender_message;
    }

    $sentMail = @mail($recipient_email, $subject, $body, $headers);
    if ($sentMail) { //output success or failure messages
        die('Thank you for your email');
    } else {
        die('Could not send mail! Please check your PHP mail configuration.');
    }
}
?>

รหัสนี้มีความเสี่ยงต่อการถูกโจมตีจากการฉีดหัวเนื่องจากการขาดการตรวจสอบและการหลบหนีจากบริบทที่เหมาะสมของการป้อนข้อมูลของผู้ใช้
Synchro

@Synchro .. นี่เป็นรหัสเดียวที่ฉันพบสำหรับไฟล์แนบหลายรายการที่ใช้งานได้สำหรับฉัน .. คุณช่วยแนะนำวิธีใช้อย่างปลอดภัย
NMathur

7

หลังจากดิ้นรนไปกับสิ่งที่แนบมาในรูปแบบที่ไม่ดีในขณะนี้เป็นรหัสที่ฉันใช้:

$email = new PHPMailer();
$email->From      = 'from@somedomain.com';
$email->FromName  = 'FromName';
$email->Subject   = 'Subject';
$email->Body      = 'Body';
$email->AddAddress( 'to@somedomain.com' );
$email->AddAttachment( "/path/to/filename.ext" , "filename.ext", 'base64', 'application/octet-stream' );
$email->Send();

6

แนวคิดการทำงาน:

if (isset($_POST['submit'])) {
    $mailto = $_POST["mailTo"];
    $from_mail = $_POST["fromEmail"];
    $replyto = $_POST["fromEmail"];
    $from_name = $_POST["fromName"];
    $message = $_POST["message"];
    $subject = $_POST["subject"];

    $filename = $_FILES["fileAttach"]["name"];
    $content = chunk_split(base64_encode(file_get_contents($_FILES["fileAttach"]["tmp_name"])));

    $uid = md5(uniqid(time()));
    $name = basename($file);
    $header = "From: " . $from_name . " <" . $from_mail . ">\r\n";
    $header .= "Reply-To: " . $replyto . "\r\n";

    $header .= "MIME-Version: 1.0\r\n";
    $header .= "Content-Type: multipart/mixed; boundary=\"" . $uid . "\"\r\n\r\n";
    $header .= "This is a multi-part message in MIME format.\r\n";
    $header .= "--" . $uid . "\r\n";

// You add html "Content-type: text/html; charset=utf-8\n" or for Text "Content-type:text/plain; charset=iso-8859-1\r\n" by I.khan
    $header .= "Content-type:text/html; charset=utf-8\n";
    $header .= "Content-Transfer-Encoding: 7bit\r\n\r\n";

// User Message you can add HTML if You Selected HTML content
    $header .= "<div style='color: red'>" . $message . "</div>\r\n\r\n";

    $header .= "--" . $uid . "\r\n";
    $header .= "Content-Type: application/octet-stream; name=\"" . $filename . "\"\r\n"; // use different content types here
    $header .= "Content-Transfer-Encoding: base64\r\n";
    $header .= "Content-Disposition: attachment; filename=\"" . $filename . "\"\r\n\r\n"; // For Attachment
    $header .= $content . "\r\n\r\n";
    $header .= "--" . $uid . "--";
    if (mail($mailto, $subject, "", $header)) {
        echo "<script>alert('Success');</script>"; // or use booleans here
    } else {
        echo "<script>alert('Failed');</script>";
    }
}

6

คำตอบข้างต้นไม่เหมาะกับฉันเนื่องจากรูปแบบไฟล์แนบที่ระบุ ( application/octet-stream) ใช้application/pdfเพื่อผลลัพธ์ที่ดีที่สุดด้วยไฟล์ PDF

<?php

// just edit these 
$to          = "email1@domain.com, email2@domain.com"; // addresses to email pdf to
$from        = "sent_from@domain.com"; // address message is sent from
$subject     = "Your PDF email subject"; // email subject
$body        = "<p>The PDF is attached.</p>"; // email body
$pdfLocation = "./your-pdf.pdf"; // file location
$pdfName     = "pdf-file.pdf"; // pdf file name recipient will get
$filetype    = "application/pdf"; // type

// creates headers and mime boundary
$eol = PHP_EOL;
$semi_rand     = md5(time());
$mime_boundary = "==Multipart_Boundary_$semi_rand";
$headers       = "From: $from$eolMIME-Version: 1.0$eol" .
    "Content-Type: multipart/mixed;$eol boundary=\"$mime_boundary\"";

// add html message body
$message = "--$mime_boundary$eol" .
    "Content-Type: text/html; charset=\"iso-8859-1\"$eol" .
    "Content-Transfer-Encoding: 7bit$eol$eol$body$eol";

// fetches pdf
$file = fopen($pdfLocation, 'rb');
$data = fread($file, filesize($pdfLocation));
fclose($file);
$pdf = chunk_split(base64_encode($data));

// attaches pdf to email
$message .= "--$mime_boundary$eol" .
    "Content-Type: $filetype;$eol name=\"$pdfName\"$eol" .
    "Content-Disposition: attachment;$eol filename=\"$pdfName\"$eol" .
    "Content-Transfer-Encoding: base64$eol$eol$pdf$eol--$mime_boundary--";

// Sends the email
if(mail($to, $subject, $message, $headers)) {
    echo "The email was sent.";
}
else {
    echo "There was an error sending the mail.";
}

$ headers = "จาก: $ จาก $ eolMIME-Version: 1.0 $ eol" ยังคงโยนข้อผิดพลาดตัวแปรที่ไม่ได้กำหนดไว้ใน $ eolMIME
หดตัว

อืม ... แทนที่"From: $from$eolMIME-Version: 1.0$eol"ด้วย"From: $from" . "$eolMIME-Version: 1.0$eol"
omikes

บางทีมันอาจจะไม่ยอมให้คุณเพิ่มตัวแปรสองตัวในแบบนั้นใน php บางเวอร์ชันมันใช้กับอันที่ฉันใช้อยู่ ขอโทษด้วยกับเรื่องนั้น. ในความเป็นจริงมีเหตุการณ์เกิดขึ้นมากมายที่คุณอาจต้องการแทนที่อินสแตนซ์ทั้งหมด$eolด้วย" . "$eolวิธีการที่ทำทั้งหมดในก้มเดียว
ทุก

2
            $to = "to@gmail.com";
            $subject = "Subject Of The Mail";
            $message = "Hi there,<br/><br/>This is my message.<br><br>";

            $headers = "From: From-Name<from@gmail.com>";
// boundary
            $semi_rand = md5(time());
            $mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";

// headers for attachment
            $headers .= "\nMIME-Version: 1.0\n" . "Content-Type: multipart/mixed;\n" . " boundary=\"{$mime_boundary}\"";

// multipart boundary
            $message = "This is a multi-part message in MIME format.\n\n" . "--{$mime_boundary}\n" . "Content-Type: text/html; charset=ISO-8859-1\"\n" . "Content-Transfer-Encoding: 7bit\n\n" . $message . "\n\n";

                $message .= "--{$mime_boundary}\n";
                $filepath = 'uploads/'.$_FILES['image']['name'];
                move_uploaded_file($_FILES['image']['tmp_name'], $filepath); //upload the file
                $filename = $_FILES['image']['name'];
                $file = fopen($filepath, "rb");
                $data = fread($file, filesize($filepath));
                fclose($file);
                $data = chunk_split(base64_encode($data));
                $message .= "Content-Type: {\"application/octet-stream\"};\n" . " name=\"$filename\"\n" .
                        "Content-Disposition: attachment;\n" . " filename=\"$filename\"\n" .
                        "Content-Transfer-Encoding: base64\n\n" . $data . "\n\n";
                $message .= "--{$mime_boundary}\n";

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

2

รหัส HTML:

<form enctype="multipart/form-data" method="POST" action=""> 
    <label>Your Name <input type="text" name="sender_name" /> </label> 
    <label>Your Email <input type="email" name="sender_email" /> </label> 
    <label>Your Contact Number <input type="tel" name="contactnumber" /> </label>
    <label>Subject <input type="text" name="subject" /> </label> 
    <label>Message <textarea name="description"></textarea> </label> 
    <label>Attachment <input type="file" name="attachment" /></label> 
    <label><input type="submit" name="button" value="Submit" /></label> 
</form> 

รหัส PHP:

<?php
if($_POST['button']){
{
    //Server Variables
    $server_name = "Your Name";
    $server_mail = "your_mail@domain.com";

    //Name Attributes of HTML FORM
    $sender_email = "sender_email";
    $sender_name = "sender_name";
    $contact = "contactnumber";
    $mail_subject = "subject";
    $input_file = "attachment";
    $message = "description";

    //Fetching HTML Values
    $sender_name = $_POST[$sender_name];
    $sender_mail = $_POST[$sender_email];
    $message = $_POST[$message];
    $contact= $_POST[$contact];
    $mail_subject = $_POST[$mail_subject];

    //Checking if File is uploaded
    if(isset($_FILES[$input_file])) 
    { 
        //Main Content
        $main_subject = "Subject seen on server's mail";
        $main_body = "Hello $server_name,<br><br> 
        $sender_name ,contacted you through your website and the details are as below: <br><br> 
        Name : $sender_name <br> 
        Contact Number : $contact <br> 
        Email : $sender_mail <br> 
        Subject : $mail_subject <br> 
        Message : $message.";

        //Reply Content
        $reply_subject = "Subject seen on sender's mail";
        $reply_body = "Hello $sender_name,<br> 
        \t Thank you for filling the contact form. We will revert back to you shortly.<br><br>
        This is an auto generated mail sent from our Mail Server.<br>
        Please do not reply to this mail.<br>
        Regards<br>
        $server_name";

//#############################DO NOT CHANGE ANYTHING BELOW THIS LINE#############################
        $filename= $_FILES[$input_file]['name'];
        $file = chunk_split(base64_encode(file_get_contents($_FILES[$input_file]['tmp_name'])));
        $uid = md5(uniqid(time()));
        //Sending mail to Server
        $retval = mail($server_mail, $main_subject, "--$uid\r\nContent-type:text/html; charset=iso-8859-1\r\nContent-Transfer-Encoding: 7bit\r\n\r\n $main_body \r\n\r\n--$uid\r\nContent-Type: application/octet-stream; name=\"$filename\"\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment; filename=\"$filename\"\r\n\r\n$file\r\n\r\n--$uid--", "From: $sender_name <$sender_mail>\r\nReply-To: $sender_mail\r\nMIME-Version: 1.0\r\nContent-Type: multipart/mixed; boundary=\"$uid\"\r\n\r\n");
        //Sending mail to Sender
        $retval = mail($sender_mail, $reply_subject, $reply_body , "From: $server_name<$server_mail>\r\nMIME-Version: 1.0\r\nContent-type: text/html\r\n");
//#############################DO NOT CHANGE ANYTHING ABOVE THIS LINE#############################

        //Output
        if ($retval == true) {
            echo "Message sent successfully...";
            echo "<script>window.location.replace('index.html');</script>";
        } else {
            echo "Error<br>";
            echo "Message could not be sent...Try again later";
            echo "<script>window.location.replace('index.html');</script>";
        }
    }else{
        echo "Error<br>";
        echo "File Not Found";
    }
}else{
    echo "Error<br>";
    echo "Unauthorised Access";
}

1

ฉันสิ้นสุดการเขียนฟังก์ชั่นการส่ง / การเข้ารหัสอีเมลของฉันเอง สิ่งนี้ทำงานได้ดีสำหรับฉันในการส่งไฟล์แนบ PDF ฉันไม่ได้ใช้คุณสมบัติอื่น ๆ ในการผลิต

หมายเหตุ: แม้ข้อมูลจำเพาะค่อนข้างชัดเจนว่าคุณต้องใช้ \ r \ n เพื่อแยกส่วนหัว แต่ฉันพบว่ามันทำงานได้เฉพาะเมื่อฉันใช้ PHP_EOL ฉันเพิ่งทดสอบสิ่งนี้บน Linux YMMV

<?php
# $args must be an associative array
#     required keys: from, to, body
#          body can be a string or a [tree of] associative arrays. See examples below
#     optional keys: subject, reply_to, cc, bcc
# EXAMPLES:
#    # text-only email:
#    email2(array(
#        'from' => 'noreply@foo.com',
#        'to' => 'jason@jasonwoof.com',
#        'subject' => 'test',
#        # body will be text/plain because we're passing a string that doesn't start with '<'
#        'body' => 'Hi, testing 1 2 3',
#    ));
#
#    # html-only email
#    email2(array(
#        'from' => 'noreply@foo.com',
#        'to' => 'jason@jasonwoof.com',
#        'subject' => 'test',
#        # body will be text/html because we're passing a string that starts with '<'
#        'body' => '<h1>Hi!</h1>I like <a href="http://cheese.com">cheese</a>',
#    ));
#
#    # text-only email (explicitly, in case first character is dynamic or something)
#    email2(array(
#        'from' => 'noreply@foo.com',
#        'to' => 'jason@jasonwoof.com',
#        'subject' => 'test',
#        # body will be text/plain because we're passing a string that doesn't start with '<'
#        'body' => array(
#            'type' => 'text',
#            'body' => $message_text,
#        )
#    ));
#
#    # email with text and html alternatives (auto-detected mime types)
#    email2(array(
#        'from' => 'noreply@foo.com',
#        'to' => 'jason@jasonwoof.com',
#        'subject' => 'test',
#        'body' => array(
#            'type' => 'alternatives',
#            'body' => array(
#                "Hi!\n\nI like cheese",
#                '<h1>Hi!</h1><p>I like <a href="http://cheese.com">cheese</a></p>',
#            )
#        )
#    ));
#
#    # email with text and html alternatives (explicit types)
#    email2(array(
#        'from' => 'noreply@foo.com',
#        'to' => 'jason@jasonwoof.com',
#        'subject' => 'test',
#        'body' => array(
#            'type' => 'alternatives',
#            'body' => array(
#                array(
#                    'type' => 'text',
#                    'body' => "Hi!\n\nI like cheese",
#                ),
#                array(
#                    'type' => 'html',
#                    'body' => '<h1>Hi!</h1><p>I like cheese</p>',
#                ),
#            )
#        )
#    ));
#
#    # email with an attachment
#    email2(array(
#        'from' => 'noreply@foo.com',
#        'to' => 'jason@jasonwoof.com',
#        'subject' => 'test',
#        'body' => array(
#            'type' => 'mixed',
#            'body' => array(
#                "Hi!\n\nCheck out this (inline) image",
#                array(
#                    'type' => 'image/png',
#                    'disposition' => 'inline',
#                    'body' => $image_data, # raw file contents
#                ),
#                "Hi!\n\nAnd here's an attachment",
#                array(
#                    'type' => 'application/pdf; name="attachment.pdf"',
#                    'disposition' => 'attachment; filename="attachment.pdf"',
#                    'body' => $pdf_data, # raw file contents
#                ),
#                "Or you can use shorthand:",
#                array(
#                    'type' => 'application/pdf',
#                    'attachment' => 'attachment.pdf', # name for client (not data source)
#                    'body' => $pdf_data, # raw file contents
#                ),
#            )
#        )
#    ))
function email2($args) {
    if (!isset($args['from'])) { return 1; }
    $from = $args['from'];
    if (!isset($args['to'])) { return 2; }
    $to = $args['to'];
    $subject = isset($args['subject']) ? $args['subject'] : '';
    $reply_to = isset($args['reply_to']) ? $args['reply_to'] : '';
    $cc = isset($args['cc']) ? $args['cc'] : '';
    $bcc = isset($args['bcc']) ? $args['bcc'] : '';

    #FIXME should allow many more characters here (and do Q encoding)
    $subject = isset($args['subject']) ? $args['subject'] : '';
    $subject = preg_replace("|[^a-z0-9 _/#'.:&,-]|i", '_', $subject);

    $headers = "From: $from";
    if($reply_to) {
        $headers .= PHP_EOL . "Reply-To: $reply_to";
    }
    if($cc) {
        $headers .= PHP_EOL . "CC: $cc";
    }
    if($bcc) {
        $headers .= PHP_EOL . "BCC: $bcc";
    }

    $r = email2_helper($args['body']);
    $headers .= PHP_EOL . $r[0];
    $body = $r[1];

    if (mail($to, $subject, $body, $headers)) {
        return 0;
    } else {
        return 5;
    }
}

function email2_helper($body, $top = true) {
    if (is_string($body)) {
        if (substr($body, 0, 1) == '<') {
            return email2_helper(array('type' => 'html', 'body' => $body), $top);
        } else {
            return email2_helper(array('type' => 'text', 'body' => $body), $top);
        }
    }
    # now we can assume $body is an associative array
    # defaults:
    $type = 'application/octet-stream';
    $mime = false;
    $boundary = null;
    $disposition = null;
    $charset = false;
    # process 'type' first, because it sets defaults for others
    if (isset($body['type'])) {
        $type = $body['type'];
        if ($type === 'text') {
            $type = 'text/plain';
            $charset = true;
        } elseif ($type === 'html') {
            $type = 'text/html';
            $charset = true;
        } elseif ($type === 'alternative' || $type === 'alternatives') {
            $mime = true;
            $type = 'multipart/alternative';
        } elseif ($type === 'mixed') {
            $mime = true;
            $type = 'multipart/mixed';
        }
    }
    if (isset($body['disposition'])) {
        $disposition = $body['disposition'];
    }
    if (isset($body['attachment'])) {
        if ($disposition == null) {
            $disposition = 'attachment';
        }
        $disposition .= "; filename=\"{$body['attachment']}\"";
        $type .= "; name=\"{$body['attachment']}\"";
    }
    # make headers
    $headers = array();
    if ($top && $mime) {
        $headers[] = 'MIME-Version: 1.0';
    }
    if ($mime) {
        $boundary = md5('5sd^%Ca)~aAfF0=4mIN' . rand() . rand());
        $type .= "; boundary=$boundary";
    }
    if ($charset) {
        $type .= '; charset=' . (isset($body['charset']) ? $body['charset'] : 'UTF-8');
    }
    $headers[] = "Content-Type: $type";
    if ($disposition !== null) {
        $headers[] = "Content-Disposition: {$disposition}";
    }

    $data = '';
    # return array, first el is headers, 2nd is body (php's mail() needs them separate)
    if ($mime) {
        foreach ($body['body'] as $sub_body) {
            $data .= "--$boundary" . PHP_EOL;
            $r = email2_helper($sub_body, false);
            $data .= $r[0] . PHP_EOL . PHP_EOL; # headers
            $data .= $r[1] . PHP_EOL . PHP_EOL; # body
        }
        $data .= "--$boundary--";
    } else {
        if(preg_match('/[^\x09\x0A\x0D\x20-\x7E]/', $body['body'])) {
            $headers[] = "Content-Transfer-Encoding: base64";
            $data .= chunk_split(base64_encode($body['body']));
        } else {
            $data .= $body['body'];
        }
    }
    return array(join(PHP_EOL, $headers), $data);
}

ฉันเพิ่งรู้ว่ารหัสของฉันเรียกว่าฟังก์ชั่นบางอย่างที่ฉันไม่ได้รวม พวกเขาแค่ทำให้แน่ใจว่าค่าจาก / ถึง / cc / etc นั้นถูกต้อง ฉันลบพวกเขาและตอนนี้รหัสนี้ทำงานตามที่เป็นอยู่ด้วยตัวเอง
JasonWoof

-1

คัดลอกรหัสจากหน้านี้ - ใช้งานในเมล ()

เขาเริ่มจากการสร้างฟังก์ชั่น mail_attachment ที่สามารถเรียกได้ในภายหลัง ซึ่งเขาทำในภายหลังด้วยรหัสแนบของเขา

<?php
function mail_attachment($filename, $path, $mailto, $from_mail, $from_name, $replyto, $subject, $message) {
    $file = $path.$filename;
    $file_size = filesize($file);
    $handle = fopen($file, "r");
    $content = fread($handle, $file_size);
    fclose($handle);
    $content = chunk_split(base64_encode($content));
    $uid = md5(uniqid(time()));
    $header = "From: ".$from_name." <".$from_mail.">\r\n";
    $header .= "Reply-To: ".$replyto."\r\n";
    $header .= "MIME-Version: 1.0\r\n";
    $header .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"\r\n\r\n";
    $header .= "This is a multi-part message in MIME format.\r\n";
    $header .= "--".$uid."\r\n";
    $header .= "Content-type:text/plain; charset=iso-8859-1\r\n";
    $header .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
    $header .= $message."\r\n\r\n";
    $header .= "--".$uid."\r\n";
    $header .= "Content-Type: application/octet-stream; name=\"".$filename."\"\r\n"; // use different content types here
    $header .= "Content-Transfer-Encoding: base64\r\n";
    $header .= "Content-Disposition: attachment; filename=\"".$filename."\"\r\n\r\n";
    $header .= $content."\r\n\r\n";
    $header .= "--".$uid."--";
    if (mail($mailto, $subject, "", $header)) {
        echo "mail send ... OK"; // or use booleans here
    } else {
        echo "mail send ... ERROR!";
    }
}

//start editing and inputting attachment details here
$my_file = "somefile.zip";
$my_path = "/your_path/to_the_attachment/";
$my_name = "Olaf Lederer";
$my_mail = "my@mail.com";
$my_replyto = "my_reply_to@mail.net";
$my_subject = "This is a mail with attachment.";
$my_message = "Hallo,\r\ndo you like this script? I hope it will help.\r\n\r\ngr. Olaf";
mail_attachment($my_file, $my_path, "recipient@mail.org", $my_mail, $my_name, $my_replyto, $my_subject, $my_message);
?>

เขามีรายละเอียดเพิ่มเติมในหน้าของเขาและตอบปัญหาบางอย่างในส่วนความเห็น


-1

แนวคิดการทำงาน 100% ในการส่งอีเมลพร้อมไฟล์แนบใน php:

if (isset($_POST['submit'])) {
  extract($_POST);
  require_once('mail/class.phpmailer.php');

  $subject = "$name Applied For - $position";
  $email_message = "<div>Thanks for Applying ....</div> ";

  $mail = new PHPMailer;
  $mail->IsSMTP(); // telling the class to use SMTP
  $mail->Host = "mail.companyname.com"; // SMTP server
  $mail->SMTPDebug = 0;
  $mail->SMTPAuth = true;
  $mail->SMTPSecure = "ssl";
  $mail->Host = "smtp.gmail.com";
  $mail->Port = 465;
  $mail->IsHTML(true);
  $mail->Username = "info@companyname.com";  // GMAIL username
  $mail->Password = "mailPassword";          // GMAIL password

  $mail->SetFrom('info@companyname.com', 'new application submitted');
  $mail->AddReplyTo("name@yourdomain.com","First Last");
  $mail->Subject = "your subject";

  $mail->AltBody = "To view the message, please use an HTML compatible email viewer!"; // optional, comment out and test

  $mail->MsgHTML($email_message);

  $address = 'info@companyname.com';
  $mail->AddAddress($address, "companyname");

  $mail->AddAttachment($_FILES['file']['tmp_name'], $_FILES['file']['name']);      // attachment

  if (!$mail->Send()) {
    /* Error */
    echo 'Message not Sent! Email at info@companyname.com';
  } else {
    /* Success */
    echo 'Sent Successfully! <b> Check your Mail</b>';
  }
}

ฉันใช้รหัสนี้สำหรับการส่งเมล smtp ของ google ด้วย Attachment ....

หมายเหตุ: ดาวน์โหลดคลัง PHPMailer จากที่นี่ -> https://github.com/PHPMailer/PHPMailer

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.