PHP mail attachment script

This custom function or PHP mail attachment script is able to send a plain text email message together with a single attachment file. The attachment file has to be uploaded first or you can use a file which already exists on your web server. There are much better and more advanced PHP scripts on the Internet, but I hope this example will help you to understand, how it’s possible to send an email message plus attachment by using some PHP code.

About PHP’s native mail() function

The mail() function doesn’t support attachment or HTML mail by default. You need to use different headers and MIME mail parts to make this possible. Many shared hosting providers doesn’t allow the usage of this function and it might be disabled.

Normally you will pass three values to the mail() function plus some headers. In the example below I skip the value for the message value, because the message is defined as a MIME part together with the 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!";
 }
}

Below is an example on how I use this function to send an email message with one attached .zip file:

$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,rndo you like this script? I hope it will help.rnrngr. Olaf";
mail_attachment($my_file, $my_path, "recipient@mail.org", $my_mail, $my_name, $my_replyto, $my_subject, $my_message);

Are you looking for a script to send multiple attachments? Try my PHP email attachment class script which is based on the same method and is another example how mail in PHP code works.

Other ways to send email with attachments using PHP

For websites or applications were an email message is an essential part for your business you should use a professional transaction email service provider and a PHP class which works for the SMTP standard. In my opinion is the PHPmailer class a very stable and flexible email script. If you like check my PHPMailer tutorial, too.

45 thoughts on “PHP mail attachment script”

  1. Hi,
    maybe the path to the file is not right?
    check this row first:

    $my_path = $_SERVER['DOCUMENT_ROOT']."/your_path_here/";

    maybe you need to use a static path?

  2. Hi Olaf,

    I tried with your example. Mail sends with an attachment. But the size of attach zip file become 0 byte. So the zip file could not work.

    I don’t know whats the problem

    Any help will be appreciated.

    Thanks in advance,
    Praveen

    1. Your file name contain spaces between name rename that file with _(underscore).

  3. That’s what I thought :)

    A document root is something else, create a new file and check the doc root using:

    `echo $_SERVER[‘DOCUMENT_ROOT’]`

  4. You need to know what your document root is, this path is required to open a file with PHP.

    Create a new PHP file and add this code:

    <?php echo $_SERVER['DOCUMENT_ROOT']; ?>

    Run this small script in your browser and the output is the document root.

    Next you need to check if this is the same location where the attachment is located.

  5. Windows servers and the document root are always a problem.

    I never used PHP on windows, check this PHP function (check also the comments)
    http://php.net/manual/en/function.getcwd.php

    Maybe your hosting provider can help you on how to identify the document root from your hosting account?

  6. Sorry didn’t understood. Can you elaborate, what should I change and where?

  7. When I run the above script on local system it prints “C:/xampp/htdocs”

    And when I run the script on server it prints: “D:Hosting4836046html”

    My server directory structure is like this:
    `www.domain.com/foldername/zipfilename.zip`

  8. Right, the script can’t include the file’s data (only the mail header for this attachment is send)

  9. Ok I understood the problem. I will ask my service provider.

    But the mail I am getting this time is containing the 0 bytes zip file attachment. Is this problem because of doc root?

  10. Thanks for immediate reply

    I checked the this row
    `$my_path = $_SERVER[‘DOCUMENT_ROOT’].”/your_path_here/”;`

    My directory structure is like this:
    `www. domain. com/ foldername/zipfilename.zip`

    When I try with static link it gives warnings:

    `Warning: filesize() [function.filesize]: stat failed for www. domain. com/foldername/zipfilename.zip on line 191
    Warning: fopen(www. domain. com/foldername/zipfilename.zip) [function.fopen]: failed to open stream: No such file or directory
    Warning: fread(): supplied argument is not a valid stream resource
    Warning: fclose(): supplied argument is not a valid stream resource`

    Any idea?

  11. Hi Olaf,

    My hosting provider replied.
    Absolute Hosting Path: D:Hosting4836046html

    Now what’s next step?

  12. Sorry, I can’t say exactly how you need to do this in Windows :(
    (I use windows only to work in Adobe Photoshop)

    First you need to find a way to handle those paths in PHP on windows.
    I’m sure Google has a lot of information on that.

    On Linux I have one file (config.php) in the doc root, creating this constant variable:
    `define(‘DOC_ROOT’, dirname(__FILE__).’/’);`

    Next I include this file in my PHP scripts, let’s say the script is one level above the root I use
    `include_once ‘../config.php’`

    After including that file I’m able to use the variable DOC_ROOT in my scripts. This way the server variable DOCUMENT_ROOT is not needed anymore.

    I hope that helps.

  13. I think this is related to the paths as well.
    If you can’t get these paths under your fingers, you will not succeed.

    Try a simple mail command first:
    `mail(‘mail@domain.com’, ‘mail subject’, ‘my first mail send via PHP’);`

  14. Thanks for your advice. I will try to find alternate solution for this.

    One more thing I just tried your code with my other hosting (linux, php).

    mail function is giving warning.
    `
    Warning: mail() [function.mail]: Bad parameters to mail() function, mail not sent. in /home/content/b/e/s/bestjobs1/html/corporate_reg/mail_attach.php on line 26
    mail send … ERROR!
    `
    any idea?

  15. Hi Olaf,

    Thanks for your support and help.

    I did it my self.

    –Removed 3rd party code–

  16. Hi,

    great that you found a working solution.
    I removed your code because it’s not tested and might not safe for other users.

  17. Hello Olaf, the mail function is not working in my site, actually it is working fine my domain but when i uploaded to this site (appiconexpress.com) it is not working well. It gives mail sending error..! (else part). Please help, thanks in advance

    1. Hi,
      it’s possible that your host doesn’t allow the use of the mail() function. Check this with your hosting provider. If they don’t allow that that function try PHPMailer.

  18. thanx for the quick reply, i tried this code with without the header part means I use if ( mail( $to, $subject,”” )) then mail is sent but with header content it does not work. Is there is problem with header part or some other issue. Please tell me the solution

    1. Do you use any attachement? Maybe custom headers are not allowed? If you use mail() for more than just a single message, the script can break on many places. You can try it for another X hours to get it working or you use a full featured mail script like PHPmailer :)

  19. Hello Olaf,
    I’ve been trying for several days now to come around a similar issue encoutered by PRAVEENKRG. My email works fine, only problem: my file is corrupted. It can open, as is always 7kb, when real file is >3Mo. I have followed advices you gave to PRAVEENKRG, I have the document_root path. This is for my company’s website, they have an server provider online: Media Temple.
    Hopefully you can give me a hint and set me on the right path for working this out.
    Cheers

    1. Hi Marianela,

      The problem from the other user was related to the (bad) server configuration. Your problem is maybe something else. I think that MediaTemplate has a limit on that mail() function because of their SPAM policy. If you look for a quick solution, try this SMTP PHP mail tutorial (Go for the part about PHPmailer and use the SMTP server provided by MT).

  20. Olaf, hi!

    Thank you for your fast answer. I check the tutorial you provide, test it and I must admit this is way over my head *sigh* Will have to do it manually until I learn my way into PHP.
    Again much appreciated for you insights.
    Cheers!

    1. Hi Marianela,
      I send you that link because it looks a lot like the mail() tutorial from this page :)
      But you’re right sending email attachments isn’t really an easy job for PHP beginners. If you try to solve it using the mail() function, than ask your hosting provider first if they support the mail() function that way.

  21. Great script but, how can you give a new name to the attached file on the fly, i mean before sending it? Lets say if a saved file name is 1234567.pdf and before sending it you want to give a nice name to the file such as Supporting Doc.pdf etc. can you do that? i tried adding a new name under the $name variable but its just showing the original file name.

    Thanks a million for this script and thanks in advance for this question!
    Scott MS

  22. Well, i figured it out! ……… first i was using a var (new file name) which was not local to the mail_attachment function and then i noticed that you can not do that. So, then i assigned a new var (new file name) to the mail_attachment function and then used it under the Content-Disposition: attachment; filename and it worked fine!

    Any way thanks again for creating such a great script!
    Scott MS

  23. Hi Olaf, I am still learner and i have a question..
    Can i attach php file in a phpMailer() and make it to execute at the client side….
    its like sending invoice copy to the coustomer. my invoice page is in php format..
    please help me with this…
    Thanks

    1. I’m glad that is not possible :)
      No you can’t execute any PHP code on the client side or without a web server.
      If you create the invoice using a PHP script, you need to create this file on your server and attach the file to your email message. This is how it works.

  24. Bastian Stassen says:

    This was a very useful post, thanks for that. Questions:
    [1] $name variable is computed but never used. Was there an intended use for $name?
    [2] Could the function be modified to allow for HTML formatted email?
    [3] Could the function be modified to work for the case when there is no attachment but everything else remains (like HTML format message etc.)?

    1. Hi Bastian,

      1) Where do you see the variable $name?
      2) Sure you can, actually this simple function is using the same functionality as this more advanced PHP mail class.
      3) The function doesn’t support any HTML and like suggested for 2) you can try that class I’ve written years ago. If you look for a mature PHP project to send HTML emails with or without attachments, you should use PHPmailer. I use that class all the time. My own PHP class was written for a better understanding, how the MIME mail format works.

  25. Bastian Stassen says:

    [1] $name variable is right in code posted at the top! $name = basename($file);

  26. Hi Bastian,
    you’re right, I couldn’t see that variable in the first sight (code blindness???).
    The filename is passed to the function as variable $filename. I removed that row you’ve mentioned, because it’s not necessary.
    Thanks

  27. antonio gonzalez says:

    Dear Mr Olaf
    I used your code.Thanks a lot. It Works perfectly, but i have a question. My server told me they are going to delete all php versións older than 5.6.

    Do you know if your code Works with php 5.6? Thanks in advance

    1. Hi,

      yes it should work, but maybe it’s a better to use a mature script like PHPmailer instead. Using a SMTP mailer class would make your email application much better.

  28. Dear Mr Olaf,
    Your code is great, thanks. May i know how can i send file attachment along with HTML text.
    Thanking You,
    Best Regards,
    Jaleel

    1. Hi Abdul,
      this PHP code example is good for sending simple emails. For better or more comfortable mail scripts, it’s much better to use a PHP class like PHPmailer. I do the same… (there is a link at the top of this tutorial)

  29. Hi Olaf
    I have one table and i will attach file in to the table file should be attached successfully but the problem is how to fetch that file from the database and send mail
    That file should be related to company detail Like agreeemnt of different different company so first i will save all file by company name and attach and save into my database
    Can you Give me a suggestion or any other idea
    Thanks in Advance

    1. Sounds like another story, do you know how to query a database? Just create a result set with all you values and use the mail function inside a loop. Just like a list of records you like to show on your website.

  30. We’ve used a solution orientated on this code and it works some time. Now the attachment get lost and only the message arrives.
    Do anybody have an idea what could be the cause?
    (We are now using PHP 5.5, SLES 12 SP1, postfix 2.11.6-24.2)

    1. Hi Peter,

      do you tried PHPMailer? This code is more for education than for web apps in production.

    1. Thanks, for the information. I stopped using the mail() function many years ago and use PHPmailer instead (via premium SMTP providers). On my server I disable the mail() function.

  31. Martijn Zentjens says:

    This script is perfect. But can you also send an email with HTML template and CSS? Because it display just as text.

    1. Hi, in that case it’s much easier to use a full functional PHP class like PHPMailer

Comments are closed.