2010-08-19 16 views
7

Gần đây tôi đã tạo mẫu trực tuyến để tạo thông tin đăng tuyển dụng cho trang web của chúng tôi. Tất cả mọi thứ được thực hiện, nó định dạng chính xác trong một trình duyệt, tự động đăng lên trang web của chúng tôi, bla bla bla.Gửi email một PDF được tạo động thông qua PHP

Phần cuối cùng tôi đang tạo là cung cấp cho quản trị viên một vài tùy chọn để phân phối bài đăng tới nhiều nơi khác nhau (qua email) một cách nhất quán, thuận tiện. Tôi đã tạo ra một trang PHP mà tạo ra một tài liệu PDF trên bay, sử dụng thư viện TCPDF. Khi tải pdf.php? Id = X, trang hiển thị tệp PDF có nội dung đăng công việc X. Điều này có nghĩa là tôi không bao giờ lưu tệp PDF vào máy chủ, chỉ cần tạo tệp đó khi đang chạy.

Nhưng tôi muốn đính kèm tệp PDF này vào email và gửi tới nhiều trường khác nhau và danh sách gửi thư nội bộ, v.v. Nếu tôi đính kèm pdf.php? Id = x vào email, nó không đính kèm PDF, nó đính kèm những gì dường như là một tập tin trống, với tên trên.

Có thể đính kèm email này vào email mà không lưu nó vào máy chủ không?


Dưới đây được thêm vào dựa trên phản ứng của JM4 để chụp thêm sự cố. Tôi đã tạo tập tin PDF tạo thành một hàm, và đặt nó vào một tệp bao gồm, chỉ để giữ cho mọi thứ dễ quản lý hơn.

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

$eol = PHP_EOL; 

// attachment name 
$filename = "_Desiredfilename.pdf"; 

include_once('pdf.php'); 
// encode data (puts attachment in proper format) 
$pdfdoc = job_posting_to_pdf($posting_id); 
$attachment = chunk_split(base64_encode($pdfdoc)); 

///////////HEADERS INFORMATION//////////// 
// main header (multipart mandatory) message 
$headers = "From: Sender_Name<[email protected]>".$eol; 
//$headers .= "Bcc: [email protected]".$eol; 
$headers .= "MIME-Version: 1.0".$eol; 
$headers .= "Content-Type: multipart/mixed; boundary=\"".$separator."\"".$eol.$eol; 
$headers .= "Content-Transfer-Encoding: 7bit".$eol; 
$headers .= "This is a MIME encoded message.".$eol.$eol; 

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

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

//Email message 
if(mail('[email protected]', 'test job posting', 'message body goes here', $headers)) { 
    echo 'mail sent'; 
} else { 
    echo 'error in email'; 
} 

Đây là một phiên bản rút gọn pdf.php:

function job_posting_to_pdf($job_id) { 
    require_once(ROOT . 'assets/libs/tcpdf/config/lang/eng.php'); 
    require_once(ROOT . 'assets/libs/tcpdf/tcpdf.php'); 
    // create new PDF document 
    $pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false); 

    // set document information 
    $pdf->SetCreator(PDF_CREATOR); 
    $pdf->SetAuthor(''); 
    $pdf->SetTitle('OPL Job Posting'); 
    $pdf->SetSubject('Job Posting'); 
    $pdf->SetKeywords('TCPDF, PDF, example, test, guide'); 

    // remove default header/footer 
    $pdf->setPrintHeader(false); 
    $pdf->setPrintFooter(false); 

    // set default monospaced font 
    $pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED); 

    //set margins 
    $pdf->SetMargins(11, PDF_MARGIN_TOP, 11); 

    //set auto page breaks 
    $pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM); 

    //set image scale factor 
    $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO); 

    //set some language-dependent strings 
    $pdf->setLanguageArray($l); 

    // --------------------------------------------------------- 

    $pdf->SetFont('times', 'I', 9); 
    $pdf->AddPage(); 

    $left_cell_width = 60; 
    $row_height = 6; 

    $pdf->Image(ROOT . 'assets/gfx/logos/OPL-Logo.jpg', 0, 5, null, 16, null, null, 'N', false, null,'R'); 
    $pdf->Ln('3'); 

    if(!$row['internal']) { 
     $pdf->Cell(0,0,'This position will be posted internally and externally, concurrently.',0,2,'C'); 
    } else { 
     $pdf->Cell(0,0,'Internal posting only.',0,2,'C'); 
    } 

    //Remainder of actual PDF creation removed to keep things simple 


    return $pdf->Output("", "S"); 
} 
+0

Hiện chúng tôi mã (hoặc tốt hơn là một bộ xương rất chặt). Có vẻ như phương pháp bạn đang sử dụng để biến URL thành tệp đính kèm bị sai. Tại sao bạn quan tâm đến việc không viết một tập tin ngay cả khi tạm thời? – symcbean

+0

http://api.joomla.org/com-tecnick-tcpdf/TCPDF.html#methodOutput Tôi đang sử dụng tùy chọn 'Tôi' cho mục đích. Tôi tự hỏi nếu tùy chọn S là những gì tôi nên sử dụng. –

+0

có bất kỳ câu trả lời nào ở đây giúp bạn không? – JM4

Trả lời

0

Bạn cũng có thể muốn xem tệp gửi dưới dạng tệp đính kèm qua PEAR Mail_Mime. Nó có thể chấp nhận một tệp đính kèm dưới dạng một chuỗi dữ liệu.

Gói RMail cũng có vẻ như sẽ thực hiện tương tự thông qua lớp stringAttachment. Bạn sẽ phải google cho nó, bởi vì tôi là một người dùng mới và vì vậy tôi chỉ có thể đăng một liên kết tại một thời điểm.

5

Nếu tôi hoàn toàn hiểu những gì bạn đang yêu cầu, điều này khá đơn giản. Tôi giả sử bạn đã có PDF được tạo ra bằng cách sử dụng một cái gì đó như fdpf hoặc tcpdf. Trong trường hợp đó - chỉ cần sử dụng đoạn mã sau:

<?php 
    // random hash necessary to send mixed content 
    $separator = md5(time()); 

    $eol = PHP_EOL; 

    // attachment name 
    $filename = "_Desiredfilename.pdf"; 

    // encode data (puts attachment in proper format) 
    $pdfdoc = $pdf->Output("", "S"); 
    $attachment = chunk_split(base64_encode($pdfdoc)); 

    ///////////HEADERS INFORMATION//////////// 
    // main header (multipart mandatory) message 
    $headers = "From: Sender_Name<[email protected]>".$eol; 
    $headers .= "Bcc: [email protected]".$eol; 
    $headers .= "MIME-Version: 1.0".$eol; 
    $headers .= "Content-Type: multipart/mixed; boundary=\"".$separator."\"".$eol.$eol; 
    $headers .= "Content-Transfer-Encoding: 7bit".$eol; 
    $headers .= "This is a MIME encoded message.".$eol.$eol; 

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

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


    //Email message 
    mail($emailto, $emailsubject, $emailbody, $headers); 

    ?> 
+0

Bạn có ý tưởng đúng. Mọi thứ ở đây đều hoạt động, nhưng khi nó được gửi đến dòng thực sự gửi email, có vẻ như nó vô thời hạn. Không có lỗi, không có gì. Có giới hạn cho tiêu đề có thể được chuyển vào không? Đây là một ít hơn 810.000 ký tự (nhưng nó chỉ là một trang PDF). –

+0

@Cory - Tập lệnh của tôi hoạt động. nếu nó được treo, có điều gì đó sai hoặc khác về kịch bản pdf của bạn. Tôi đã sử dụng ở trên cho 100 trang pdf mà không có vấn đề. Không có giới hạn về số lượng tiêu đề hơn số lượng tiêu đề. Đăng mã thực của bạn trong một bản chỉnh sửa để chúng tôi có thể xem xét. – JM4

+0

Cảm ơn JM4, tôi đã thêm vào mã trong bài đăng gốc. Như tôi đã nói, nó sẽ thực hiện mọi thứ trừ cuộc gọi mail() thực tế. Vì vậy, tôi có thể xuất ra các tiêu đề $ thông qua echo mà không có probs. –

1

Tôi chỉ có con số này ra và nhãn cầu của tôi là chắc chắn đau bởi cuối cùng thì ...

1) Bạn cần cài đặt PHPMailer với php máy chủ.

2) Bao gồm các lớp PHPMailer trong kịch bản TCPDF của bạn, như vậy (đường dẫn của bạn có thể thay đổi):

require_once('../PHPMailer_v5.1/class.phpmailer.php'); 

3) Bây giờ sau khi mã pdf của bạn chỉ đơn giản là nói chuyện với PHPMailer như vậy:

$filename = "custompdf_$name_$time.pdf"; 

$pdf->Output($filename, 'F'); // save the pdf under filename 

$mail = new PHPMailer(); $mail->IsSMTP(); 

$mail->Host = "mail.yourhost.com"; 
$mail->SMTPAuth = true;     // enable SMTP authentication 
$mail->Port  = 26;     // set the SMTP port for the GMAIL server 
$mail->Username = "user+yourhost.com"; // SMTP account username 
$mail->Password = "topsecret";  // SMTP account password 

$mail->From = "[email protected]"; 
$mail->FromName = "Stack Overflower"; 
$mail->AddAddress($email, $name); // in this case the variable has been passed 
$mail->AddCC("[email protected]", "Johnny Person"); // in this case we just hard code it 
$mail->SMTPDebug = 0; // use 2 for debugging the email send 

$pdf_content = file_get_contents($filename); 

$mail->WordWrap = 50; 
$mail->AddStringAttachment($pdf_content, "custompdf_for_$name_$time.pdf", "base64", "application/pdf"); // note second item is name of emailed pdf 
$mail->IsHTML(true); 
$mail->Subject = "Your pdf is here"; 
$mail->Body = "Dear $name,<br> 
Here is your custom generated pdf generated at $t.<br><br> 
Thank you"; 
if(!$mail->Send()) { 
    echo "Sorry ... EMAIL FAILED"; 
    } else { echo "Done. . . Email sent to $email at $t."; } 

unlink($filename); // this will delete the file off of server 

Tất nhiên bạn có nhiều tùy chọn cho email được gửi, như không sử dụng html hoặc gửi cả html và văn bản, thêm nhiều người nhận và/hoặc cc, v.v.

CHỈNH SỬA: Thao tác này sẽ lưu tệp tạm thời trên máy chủ nhưng nó sẽ tự dọn dẹp sau khi có lệnh hủy liên kết.

+0

Giải pháp của bạn ngụ ý rằng anh ta cần tải lên các tập lệnh PHP Mailer vào thư mục của mình mà không phải là trường hợp. Các lệnh PHP Mail() đơn giản sẽ gửi email. Bạn cũng không cần phải lưu tệp PDF như bạn ngụ ý, nó hoạt động tốt như $ pdf-> Output ($ filename, 'S'); – JM4

+0

Thanks- Trên thực tế, trong khi mail hoạt động, phpmailer là cách tốt hơn, tức là tôi cần các chức năng SMTP đã được xác thực. Tôi cho rằng tùy chọn 'S' sẽ giữ cho công việc tạm thời trong bộ nhớ và không phải là một tệp thực trên đĩa ... nếu bạn có thể cung cấp một ví dụ làm việc ... Tôi đã không mở được lỗi luồng. – Mischa

0

Tôi đồng ý về việc sử dụng thư viện thư thay cho việc tạo thông điệp mime bằng tay với hàm mail() mặc định. SwiftMailer là một thư viện thư PHP nguồn mở tốt khác. Dưới đây là sample code để sử dụng nội dung động dưới dạng tệp đính kèm mà không phải lưu nội dung đó vào hệ thống tệp trước.

0

tiêu đề của bạn dường như là một trong số ít:

  • application/octet-stream nên trở thành application/octetstream

  • Content-Disposition: attachment .. nên trở thành Content-Disposition: attachment; filename="' . basename($filename) . '"

heres những gì tiêu đề attachement nên hình như:

// attachment 
$headers .= "--".$separator.$eol; 
$headers .= "Content-Type: application/octetstream;".$eol; //Fixed 
$headers .= "Content-Transfer-Encoding: base64".$eol; 
$headers .= 'Content-Disposition: attachment; filename="' . basename(filename).'"'.$eol; 
$headers .= 'Content-ID: <' . basename($filename) . '>' . $eol . $eol //EOL X2 Before 
$headers .= $attachment; 

//Run the above in a loop for multiple attachments, after add the final line 
$headers .= '--' . $separator . '--' . $eol; 

này được lấy từ một trong các ứng dụng làm việc của tôi, heres vòng lặp nếu bạn muốn nhìn thấy nó:

foreach ($this->attachments as $attachment) { 
    if (file_exists($attachment['file'])) { 
     $handle = fopen($attachment['file'], 'r'); 
     $content = fread($handle, filesize($attachment['file'])); 

     fclose($handle); 

     $message .= '--' . $boundary . $this->newline; 
     $message .= 'Content-Type: application/octetstream' . $this->newline; 
     $message .= 'Content-Transfer-Encoding: base64' . $this->newline; 
     $message .= 'Content-Disposition: attachment; filename="' . basename($attachment['filename']) . '"' . $this->newline; 
     $message .= 'Content-ID: <' . basename($attachment['filename']) . '>' . $this->newline . $this->newline; 
     $message .= chunk_split(base64_encode($content)); 
    } 
} 
$message .= '--' . $boundary . '--' . $this->newline; 
+0

Bạn sẽ làm như thế nào nếu bản pdf không tồn tại trên máy chủ nhưng thông qua url với tcpdf? – Alex