Send attachments with PHP Mail()?

前端 未结 14 2479
北恋
北恋 2020-11-21 04:46

I need to send a pdf with mail, is it possible?

$to = \"xxx\";
$subject = \"Subject\" ;
$message = \'Example message with html\';
$header         


        
相关标签:
14条回答
  • 2020-11-21 05:14

    I ended up writing my own email sending/encoding function. This has worked well for me for sending PDF attachments. I have not used the other features in production.

    Note: Despite the spec being quite emphatic that you must use \r\n to separate headers, I found it only worked when I used PHP_EOL. I have only tested this on 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);
    }
    
    0 讨论(0)
  • 2020-11-21 05:15

    None of the above answers worked for me due to their specified attachment format (application/octet-stream). Use application/pdf for best results with PDF files.

    <?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.";
    }
    
    0 讨论(0)
提交回复
热议问题