Downloading Gmail attachments using PHP

Automatically extracting attachments from Gmail can be important for reasons where you need to process the attached files periodically with a CRON job. Also it can be useful for automatically archiving important attachments. Below is a simple proof-of-concept plain PHP code, devoid of any object-oriented features that extracts attachments from your Gmail account. It uses PHPs imap extension to access the inbox.

Before you proceed make sure that imap is enabled in your Gmail settings page. All attachments downloaded in the following code are saved in the current folder, which you can easily change to point to another directory. Downloadable code is given at the end of the post.

 *	Gmail attachment extractor.
 *	Downloads attachments from Gmail and saves it to a file.
 *	Uses PHP IMAP extension, so make sure it is enabled in your php.ini,
 *	extension=php_imap.dll

/* connect to gmail with your credentials */
$hostname = '{}INBOX';
$username = 'YOUR_GMAIL_USERNAME'; # e.g
$password = 'YOUR_GMAIL_PASSWORD';

/* try to connect */
$inbox = imap_open($hostname,$username,$password) or die('Cannot connect to Gmail: ' . imap_last_error());

/* get all new emails. If set to 'ALL' instead 
 * of 'NEW' retrieves all the emails, but can be 
 * resource intensive, so the following variable, 
 * $max_emails, puts the limit on the number of emails downloaded.
$emails = imap_search($inbox,'ALL');

/* useful only if the above search is set to 'ALL' */
$max_emails = 16;

/* if any emails found, iterate through each email */
if($emails) {
    $count = 1;
    /* put the newest emails on top */
    /* for every email... */
    foreach($emails as $email_number) 

        /* get information specific to this email */
        $overview = imap_fetch_overview($inbox,$email_number,0);
        /* get mail message */
        $message = imap_fetchbody($inbox,$email_number,2);
        /* get mail structure */
        $structure = imap_fetchstructure($inbox, $email_number);

        $attachments = array();
        /* if any attachments found... */
        if(isset($structure->parts) && count($structure->parts)) 
            for($i = 0; $i < count($structure->parts); $i++) 
                $attachments[$i] = array(
                    'is_attachment' => false,
                    'filename' => '',
                    'name' => '',
                    'attachment' => ''
                    foreach($structure->parts[$i]->dparameters as $object) 
                        if(strtolower($object->attribute) == 'filename') 
                            $attachments[$i]['is_attachment'] = true;
                            $attachments[$i]['filename'] = $object->value;
                    foreach($structure->parts[$i]->parameters as $object) 
                        if(strtolower($object->attribute) == 'name') 
                            $attachments[$i]['is_attachment'] = true;
                            $attachments[$i]['name'] = $object->value;
                    $attachments[$i]['attachment'] = imap_fetchbody($inbox, $email_number, $i+1);
                    /* 4 = QUOTED-PRINTABLE encoding */
                    if($structure->parts[$i]->encoding == 3) 
                        $attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']);
                    /* 3 = BASE64 encoding */
                    elseif($structure->parts[$i]->encoding == 4) 
                        $attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']);
        /* iterate through each attachment and save it */
        foreach($attachments as $attachment)
            if($attachment['is_attachment'] == 1)
                $filename = $attachment['name'];
                if(empty($filename)) $filename = $attachment['filename'];
                if(empty($filename)) $filename = time() . ".dat";
                /* prefix the email number to the filename in case two emails
                 * have the attachment with the same file name.
                $fp = fopen($email_number . "-" . $filename, "w+");
                fwrite($fp, $attachment['attachment']);
        if($count++ >= $max_emails) break;

/* close the connection */

echo "Done";



Check updated article here.

Download Code file
Downloads : [downloadcounter(Gmail-Imap)] / File size : [downloadsize(Gmail-Imap)]

34 thoughts to “Downloading Gmail attachments using PHP”

  1. The attachments are stored in the directory where the source file is located. However you can change the path to a different one by adding the path information to the filename. So to download the attachments to the directory “d:\gmail\attachments”, you can change the following line in the code (line no. 129):

    $fp = fopen($email_number . “-” . $filename, “w+”);

    to the following:

    $fp = fopen(“d:/gmail/attachments/” . $email_number . “-” . $filename, “w+”);

  2. hi sameer, i changed it to what ever you said..but still its not working….it says “Done”..i checked my path but no luck…any suggestions…

  3. $emails = imap_search($inbox,’ALL’);

    After the above line check if any emails are returned using print_r


    This should return and array something like the following, no empty array should be returned.

    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4

  4. I would like to use this script to first save a max of 8 attachments to a directory and then write a new row containing the attachment filenames, email body, subject and from address to a mySQL database. Is this possible???

  5. Do you have a spam problem on this blog; I also am a blogger, and I was curious about your situation; we have developed some nice
    procedures and we are looking to trade strategies with
    other folks, why not shoot me an e-mail if interested.

  6. Nice script, but i have a question. I need it to do 2 things, 1 – get an email from just 1 address and 2 – download the attachment from the email?

  7. How I order the images from by most recent? Showing the most recent first, and the oldest last?

    The rsort() function doesn’t seem to work?

  8. Hi Sameer,

    Thanks a lot for the tutorial. I am having a connection error. I doubt I am doing something wrong. can you please help?

  9. Thanks buddy….Its really awesome. After searching for 3 days finally your code worked.


  10. Great great tutorial! When I use it in non gmail account eg. my own email hosting, the $emails = imap_search($inbox,’NEW’); with NEW paramater must work? Because it is not working..

  11. Can’t seem to get this to work. I get an error log report with the following:

    [10-Feb-2013 14:55:29] PHP Warning: imap_open() [function.imap-open]: Couldn’t open stream {}INBOX in /home/******/public_html/ on line 24

  12. Make sure SSL is enabled on your PHP installation. The OpenSSL extension should be enabled. The IMAP Client library (with SSL) depends on this.

  13. Hey,

    Thanks for the script. Works great! Is there a attachement size limit? I can’t seem to save a 2.4mb image, whereas a 1mb saves fine


  14. Hi,

    Thanks for the code it worked like charm. It seems that is also downloading the inline images of mail content(mail body) if any. What if i don’t need any inline images to download and I only need attachments to download.

    Please suggest…


  15. Hi,

    Great post, works great.

    How do i save attachments embedded into the mail body, like images?


  16. This code doesn’t work fine in Ubuntu.
    – Saving the attachment in the directory
    – Contents of attachment
    Please let me know what to do

  17. Greetings

    I am trying to download from other email server not gmail, I did print_r($emails);
    It shows 1 2 3 4 5 as you wrote above in one post . I am running the code on ubuntu,
    It says done but the attachement is not there in the soucre directory.

    Is it exlusively for gmail. I am using it for pop3}INBOX
    This doesnt work for pop3 I think?

    Any Comments ?


  18. Greetings again

    I should have done this before the first comment.

    Ok I change pop3 to imap in the server string

    It gives one Notice after Done

    DonePHP Notice: Unknown: rsh to IMAP server timed out (errflg=1) in Unknown on line 0


  19. Thanks for this snipped of code! That really helped me.

    Is it possible you mixed comments when decoding attachments from base64/quoted-printable encoding? It seems to me the comments are in the wrong order to the code itself!

    Kind regards

  20. Thanks for the code. It works perfectly. Do have a question though:

    /* get mail message */
    $message = imap_fetchbody($inbox,$email_number,2);

    1. Where do I find what 2 stands for? Can not seen to find what specific parts there are.
    2. Why is the above line actually in your code example when you don’t use it any further in your code?

  21. Greetings! Very helpful advice witthin this article! It is the little changes that will make the modt significant changes.
    Thanks a lott for sharing!

  22. Firstly really thankyou for script…………..I am facing some issue when getting the body content with attachment, the content is not coming in proper format some encode is coming along.

    Thanks in Advance

Leave a Reply

Your email address will not be published.