2011-09-02 64 views
5

Tôi có một tập lệnh PHP gửi một email HTML có kèm theo hình ảnh. Nó hoạt động beauifully, tuy nhiên, tôi không thể có được các tập tin đính kèm để hiển thị trong một thẻ <img> trong cơ thể email. Tệp đính kèm được gọi là postcard.png và tên tệp gốc trên máy chủ là 4e60348f83f2f.png. Tôi đã thử cung cấp URL hình ảnh dưới dạng nhiều thứ khác nhau: cid:postcard.png, cid:4e60348f83f2f.png, postcard.png4e60348f83f2f.png. Không có gì hiệu quả.cách gửi email HTML có hình ảnh đính kèm bên trong với PHP

Tôi nghĩ rằng phần quan trọng mà tôi đang làm sai là ở đây, bởi vì điều này làm cho nó một tập tin đính kèm tách thay vì một tập tin đính kèm nội tuyến mà tôi có thể sử dụng:

Content-Transfer-Encoding: base64 
Content-Disposition: attachment; 
    filename="$fname" // i.e.: "postcard.png" 

tôi đã cố gắng thay đổi nó để sử dụng một CID nhưng tôi không thực sự biết làm thế nào để làm điều đó, và didnt' công việc này ở tất cả:

Content-Transfer-Encoding: base64 
Content-ID: <$fname> // i.e.: postcard.png 

Dưới đây là toàn bộ mã: (Nó dựa trên this code từ một bình luận trong trang php mail().)

<?php 
$to  = "[email protected]"; 
$email = "[email protected]"; 
$name = "Namename"; 
$subject = "An inline image!"; 
$comment = "Llookout <b>Llary</b> it's <br> the <b>Ll</b>andllord!<br><img src='cid:postcard.png'><br><img src='cid:4e60348f83f2f.png'><img src='postcard.png'><br><img src='4e60348f83f2f.png'>"; 

$To   = strip_tags($to); 
$TextMessage =strip_tags(nl2br($comment),"<br>"); 
$HTMLMessage =nl2br($comment); 
$FromName =strip_tags($name); 
$FromEmail =strip_tags($email); 
$Subject  =strip_tags($subject); 

$boundary1 =rand(0,9)."-" 
    .rand(10000000000,9999999999)."-" 
    .rand(10000000000,9999999999)."=:" 
    .rand(10000,99999); 
$boundary2 =rand(0,9)."-".rand(10000000000,9999999999)."-" 
    .rand(10000000000,9999999999)."=:" 
    .rand(10000,99999); 

$filename1 = "4e60348f83f2f.png"; //name of file on server with script 
$handle  =fopen($filename1, 'rb'); 
$f_contents =fread($handle, filesize($filename1)); 
$attachment=chunk_split(base64_encode($f_contents)); 
fclose($handle); 

$ftype  ="image/png"; 
$fname  ="postcard.png"; //what the file will be named 


$attachments=''; 
$Headers  =<<<AKAM 
From: $FromName <$FromEmail> 
Reply-To: $FromEmail 
MIME-Version: 1.0 
Content-Type: multipart/mixed; 
    boundary="$boundary1" 
AKAM; 

$attachments.=<<<ATTA 
--$boundary1 
Content-Type: $ftype; 
    name="$fname" 
Content-Transfer-Encoding: base64 
Content-Disposition: attachment; 
    filename="$fname" 


$attachment 

ATTA; 


$Body  =<<<AKAM 
This is a multi-part message in MIME format. 

--$boundary1 
Content-Type: multipart/alternative; 
    boundary="$boundary2" 

--$boundary2 
Content-Type: text/plain; 
    charset="windows-1256" 
Content-Transfer-Encoding: quoted-printable 

$TextMessage 
--$boundary2 
Content-Type: text/html; 
    charset="windows-1256" 
Content-Transfer-Encoding: quoted-printable 

$HTMLMessage 

--$boundary2-- 

$attachments 
--$boundary1-- 
AKAM; 

// Send email 
$ok=mail($To, $Subject, $Body, $Headers); 
echo $ok?"<h1> Mail sent!</h1>":"<h1> Mail not sent!</h1>"; 
?> 
+2

Sử dụng [PHPMailer] (http://phpmailer.worxware.com) hoặc [Swiftmailer] (http://swiftmailer.org). Cả hai đều cho phép các tệp đính kèm trong dòng hoàn toàn KHÔNG BẤT K P, không giống như những gì bạn đang trải qua để xây dựng thông điệp MIME từ đầu. –

+0

Nó không phải là nó không thể làm điều đó bằng tay, nhưng bằng cách sử dụng Swiftmailer hoặc PHPMailer sẽ được cách ít cồng kềnh. - Có thể trùng lặp [Gửi email bằng PHPMailer - nhúng hình ảnh vào trong cơ thể] (http://stackoverflow.com/questions/3708153/send-email-with-phpmailer-embed-image-in-body) – mario

+1

@Marc B: Tôi không biết, tôi đã kéo một lần gõ hangnail một lần với PHPMailer, nó hơi đau. –

Trả lời

14

Cuối cùng tôi đã tìm thấy câu trả lời, điều này hóa ra lại rất đơn giản. This page là những gì đã giúp tôi tìm ra nó, nhưng tôi sẽ trình bày các phần mà tôi cần để hoàn thành nó dưới đây.

Trước hết, đó là việc tạo ra các chuỗi ranh giới, và hình ảnh, mã hóa một cách chính xác và chửi rủa:

// Create a boundary string. It needs to be unique (not in the text) so ... 
// We are going to use the sha1 algorithm to generate a 40 character string: 
$sep = sha1(date('r', time())); 

// Also now prepare our inline image - Also read, encode, split: 
$inline = chunk_split(base64_encode(file_get_contents('figure.gif'))); 

Trong phần HTML của email, hình ảnh được tham chiếu như thế này (bằng cách sử dụng chuỗi ranh giới):

<img src="cid:PHP-CID-{$sep}"> 

sau đó, bạn tạo ra một phần khác của email bên dưới phần HTML cho tập tin đính kèm nội tuyến, như thế này:

--PHP-related-{$sep} 
Content-Type: image/gif 
Content-Transfer-Encoding: base64 
Content-ID: <PHP-CID-{$sep}> 
{$inline} 

... và đó là điều đó! Dễ dàng hơn việc triển khai PHPmailer hoặc bất kỳ thư viện nào khác, nếu đây là tất cả những gì bạn đang làm. Không nghi ngờ gì về nhiệm vụ phức tạp hơn, bạn sẽ muốn nhận được một trong những thư viện đó.

+0

Tôi không thể đính kèm theo câu trả lời này, tôi làm như sau: http://pastebin.com/z8LqAHCB –

0

Tôi khuyên bạn nên sử dụng PHPMailer nhưng vì bạn nói bạn không muốn tôi đề xuất sửa lỗi nhanh này.

Đặt URL tuyệt đối bên trong thẻ img, nếu bạn gửi email HTML, nó sẽ hoạt động.

<img src="http://example.com/image.jpg"/> 
+1

Cảm ơn, tuy nhiên tôi đang xóa hình ảnh khỏi máy chủ ngay sau khi gửi email, do đó sẽ không hoạt động, cũng như vì nhiều ứng dụng email không cho phép liên kết nóng trong email. – brentonstrine

+0

Sử dụng phương pháp này, hình ảnh sẽ bị chặn trong các ứng dụng email khác nhau – ljelewis

Các vấn đề liên quan