PHP IMAP - Fetch email
New here? Learn about Bountify and follow @bountify to get notified of new bounties! x

I have a PHP application which fetches email using IMAP.

Gmail considers my application of "low-security" and I have to click on "enable low-security applications" to have my application access gmail IMAP, and my app most of the times gets blocked for "suspicious" activity and I need to manually enable it in every email inbox I crawl.

My code currently looks something like this (I simplified it):

The main problem seems to be here:

$this->server = '{'. $imap. ':' .$port.'/ssl}';
$this->connection = imap_open($this->server, $emailAddress, $password);

Is there a way to make this connection "more secure" to comply with Gmail standards regarding the IMAP connection so I don't get any "suspicious activity" warnings? Thanks!

Please provide a tested and working solution. Thanks

awarded to Codeword

Crowdsource coding tasks.

3 Solutions

Gmail requires OAuth2.0 authentication for gmail if you want to use it in PHP. You should use a PHP extension to get that, it will be easier. Here is an extension that seems to do the work :

Thanks, do you have a solution that does not use a php extension? Extensions have security issues and get outdated.
georgefountain 1 year ago
Just seen the last comment on Codeword solution, if there is an issue with the SSL certificate, you can try to disable the check when connecting using the "/novalidate-cert". This may reduce the "suspicious activity warning : $this->server = '{'. $imap. ':' .$port.'/ssl/novalidate-cert}';
kerncy 1 year ago
Thanks. Can we have a valid ssl certificate? Can you provide a solution without an extension? Thanks so much
georgefountain 1 year ago

You need to use OAuth authentication, otherwise GMail will not consider your application secure.

Here's a quick tutorial on how to implement it as quickly as possible:

At the bottom the tutorial mentions why you had to enable low-security applications to make it work.

Good luck! :)

.Your "solution" has Python instead of php and is a badly written article. As bountify states please post a complete working solution so that it can be accepted. Thanks
georgefountain 1 year ago
Can you explain what is the python part for? I don't understand it. Thanks
georgefountain 1 year ago
Winning solution

Hello, the solution to your problem is simple.

Step 1. Go to
Select the following two fields from their drop-down lists 'Select app = mail' and 'Select device =Other'.

Step 2. Click "GENERATE" button and save the app password shown to you.

After this, you need two file index.php  Imap.php

Note : You can use your own code but make sure to use you App password as your password when passing parameters to imap_open() function. Or you can also use the file below

Thank you.

index.php contents


// include Imap class

// create Imap_parser Object
$parse = new Imap_parser();

$email ='';
$em=end(explode('@', $email));
switch ($em) {
case '':
$password= 'App password you got in step 2';

case '':


// data '{}INBOX' or notls
$data = array(
// email account
'email' => array(
'hostname' => $hostname,
'username' => $email,
'password' => $password

// inbox pagination
'pagination' => array(
'sort' => 'DESC', // or ASC
'limit' => 5,
'offset' => 0

// get inbox. Array
$result = $parse->inbox($data);
echo '';
echo '';

imap.php contents


class Imap_parser {

function inbox($data)

    $result = array();

    $imap = imap_open($data['email']['hostname'], $data['email']['username'], $data['email']['password']) or die ('Cannot connect to ' . imap_last_error());

    if ($imap) {

        $result['status'] = 'success';
        $result['email']  = $data['email']['username'];

        $read = imap_search($imap, 'ALL');

        if($data['pagination']['sort'] == 'DESC'){

        $num = count($read);

        $result['count'] = $num;

        $stop = $data['pagination']['limit'] + $data['pagination']['offset'];

        if($stop > $num){
            $stop = $num;

        for ($i = $data['pagination']['offset']; $i < $stop; $i++) {

            $overview   = imap_fetch_overview($imap, $read[$i], 0);
            $message    = imap_body($imap, $read[$i], 0);
            $header     = imap_headerinfo($imap, $read[$i], 0);
            $mail       = $header->from[0]->mailbox . '@' . $header->from[0]->host;
            $image = '';

            $message = preg_replace('/--(.*)/i', '', $message);
            $message = preg_replace('/X\-(.*)/i', '', $message);
            $message = preg_replace('/Content\-ID\:/i', '', $message);

            $msg = '';            

            if (preg_match('/Content-Type/', $message)) {
                $message = strip_tags($message);
                $content = explode('Content-Type: ', $message);
                foreach ($content as $c) {
                    if (preg_match('/base64/', $c)) {
                        $b64 = explode('base64', $c);
                        if (preg_match('/==/', $b64[1])) {
                            $str = explode('==', $b64[1]);
                            $dec = $str[0];
                        } else {
                            $dec = $b64[1];
                        if (preg_match('/image\/(.*)\;/', $c, $mime)) {
                            $image = 'data:image/' . $mime[1] . ';base64,' . trim($dec);
                    } else {
                        if (!empty($c)) {
                            $msg = $c;
            } else {
                $msg = $message;

            $msg = preg_replace('/text\/(.*)UTF\-8/', '', $msg);
            $msg = preg_replace('/text\/(.*)\;/', '', $msg);
            $msg = preg_replace('/charset\=(.*)\"/', '', $msg);
            $msg = preg_replace('/Content\-Transfer\-Encoding\:(.*)/i', '', $msg);

            $result['inbox'][] = array(
                'id' => $read[$i],
                'subject' => strip_tags($overview[0]->subject),
                'from' => $overview[0]->from,
                'email' => $mail,
                'date' => $overview[0]->date,
                'message' => trim($msg),
                'image' => $image

            $result['pagination'] = array(
                'sort' => $data['pagination']['sort'],
                'limit' => $data['pagination']['limit'],
                'offset' => array(
                    'back' => ($data['pagination']['offset'] == 0 ? null : $data['pagination']['offset'] - $data['pagination']['limit']),
                    'next' => ($data['pagination']['offset'] < $num ? $data['pagination']['offset'] + $data['pagination']['limit'] : null)



    } else {
        $result['status'] = 'error';

    return $result;




Thanks but the problem is not the password. The problem seems to be the ssl with no certificate which makes the connection insecure. This doesn't solve the problem
georgefountain 1 year ago
okay, thanks for your feedback, georgefountain.
Codeword 1 year ago
You are welcome. Hoping that you can find the solution : ) Thanks
georgefountain 1 year ago
P.S: Codeword, have you tested your solution? Does doing just that remove the security warnings?
georgefountain 1 year ago
yes, I have tested this code and it removes the security warnings. I hope it works for you too. Thank you.
Codeword 1 year ago
Codeword, please can you check how to add a valid security certificate to the connection to make it more secure? If so, I would like to award the bounty to you. Thanks
georgefountain 12 months ago
Do you have an ssl cerificate for you domain?
Codeword 12 months ago
Yes i do.
georgefountain 12 months ago
Okay, Have you tried the above solution?
Codeword 12 months ago
Your solution only applies for Gmail. All other email providers tell me that my connection is insecure. How can we can the connection secure?
georgefountain 12 months ago
"Low security application". Same problem with outlook
georgefountain 12 months ago
I provided the solution specifically for gmail, because it was explicity mentioned "to comply with Gmail standards" in the bounty description. Thank you.
Codeword 12 months ago
Provide a full solution to the problem to get a 100% extra bonus tip
georgefountain 12 months ago
Hey, george, I have found this solution online, you may want to try this. Let me know how it goes. Thank you. Note : I don't have an SSL certified domain, so cannot test solution.
Codeword 12 months ago
Thanks. Can you modify your code with what the article suggests? Thanks
georgefountain 12 months ago
I don't see anything on the article about using a security certificate. I don't understand why you sent the article..
georgefountain 12 months ago
george, Good news, With a little modifications the code seems to work with outlook too. I have tested and it is now working in outlook too.I have updated the code above. Note : requirements of every email provider is a bit different so, I have implemented a switch case here.
Codeword 12 months ago
Thats fantastic news! The code is a bit hard to read. Could you please paste into paste bin? The trick was adding the imap. Host to remove the warning? What made the difference? Thanks so much for the hard work!
georgefountain 12 months ago
In other words, what is it that removed the warning in outlook?
georgefountain 12 months ago
Here it is I hope it works for you.
Codeword 12 months ago
Thanks thst works better! So about my question, what made the difference? Thanks
georgefountain 12 months ago
Well I am very much clear about the gmail but, I am not very much sure about outlook, I looked at the imap settings in my outlook account and tried those settings and it worked. Thank you.
Codeword 12 months ago
Is everything working like you wanted ? Thanks
Codeword 12 months ago
Thank you Georgefountain.
Codeword 12 months ago
View Timeline