GrahamMorbyDev's avatar

PHP-imap get all mail

Hi Guys

Another question on Email. I m using php-imap package to get all mail from a Gmail account.

Now I can get a single message but what I'm struggling to do is get all mail at once

public function GetMail() {
        $mailbox = new PhpImap\Mailbox('{imap.gmail.com:993/imap/ssl}INBOX', '[email protected]', 'password', __DIR__);
        // Read all messaged into an array:
        $mailsIds = $mailbox->searchMailbox('ALL');
        if(!$mailsIds) {
            return ('Mailbox is empty');
        }
        // Get the first message and save its attachment(s) to disk:
        $mail = $mailbox->getMail($mailsIds[1]);
        dd($mail);
    }

if I remove the [1] I get the error of 'cant get property of non-object'

The docs are pretty slim to be honest so just wondering if anyone has any experience with the package and have managed to do what I'm trying to do

0 likes
15 replies
Nash's avatar

I've used it to fetch messages from a mailbox via IMAP so I know that it works for that purpose. Haven't tried with Gmail but it should work just the same.

One thing to pay special attention to is when dealing with multipart messages and how to fetch individual parts. Luckily the docs are pretty good: https://docs.zendframework.com/zend-mail/read/#working-with-messages

GrahamMorbyDev's avatar

Totally just getting this 'cannot read - connection closed? ' at the moment

GrahamMorbyDev's avatar

I have indeed ,

 public function GetMail() {

        $mail = new Imap(array('host'     => 'imap.gmail.com',
            'user'     => '[email protected]',
            'port'     => '993',
            'password' => '********',
            'ssl'      => 'tls',
            'auth'     => 'login'
        ));

        echo $mail->countMessages() . " messages found\n";
        foreach ($mail as $message) {
            printf("Mail from '%s': %s\n", $message->from, $message->subject);
        }
    }
Nash's avatar

You may also need to turn on "Allow less secure apps" in your Google account settings. I got it working with the following settings after that:

$mail = new Imap([
    'host' => 'imap.gmail.com',
    'user' => '[email protected]',
    'password' => '********',
    'ssl' => 'ssl',
    'port' => 993
]);

Edit: apparently a "less secure app" is anything that doesn't use OAuth

https://blogs.msmvps.com/jcoehoorn/blog/2017/05/04/what-are-less-secure-apps-in-google/

You may also want to turn on two-factor auth after that and make an app-specific password.

GrahamMorbyDev's avatar

That worked! Thank you very much , now I need to play to get stuff out!

GrahamMorbyDev's avatar

One last question @Nash , any ideas how to return all messages as an object and not just the count ?

Nash's avatar

You can iterate over the messages or fetch a single message:

// Iterate over the messages
foreach ($mail as $messageNum => $message) {
    // do stuff ...
}

// Single message
$message = $mail->getMessage($messageNum);

Fetching the content is a bit trickier. You can use $message->getContent() for that but if you have a multipart message then you may need to loop through the parts in order to get the part you're looking for.

Read through the docs, especially the "Fetching, counting, and removing messages" and "Working with messages" sections:

https://docs.zendframework.com/zend-mail/read/#fetching-counting-and-removing-messages

GrahamMorbyDev's avatar

Kinda wish id just giving them google mail in the browser lol

Im currently here

 //Get all mail
    public function GetMail() {

        $mail = new Imap(array(
            'host' => 'imap.gmail.com',
            'user' => [email protected]',
            'password' => '*********',
            'ssl' => 'ssl',
            'port' => 993
        ));

        $mail->countMessages();
        $content = array([ ]);
        foreach ($mail as $messageNum => $message) {
            $content = array([
               'from' => $message->from,
                'subject' =>$message->subject
            ]);
        }
        return $content;
    }

Here is where I'm lost what is the id returned ie $message-> id, cause that doesn't exist and also why am I only getting one message

Sorry for so many questions and really do appreciate your help

Nash's avatar

why am I only getting one message

You are re-declaring the array on every loop instead of adding an element. Also, you should do array() or [], not both at the same time.

$content = [];
foreach ($mail as $messageNum => $message) {
    $content[] = [
        'from' => $message->from
    ];
}

Read the relevant documentation and try to find your way through. In this case, the problem has more to do with arrays and PHP syntax.

GrahamMorbyDev's avatar

yeah im getting there I moved on a bit now , Thanks again for your help buddy

Nash's avatar

Looking back at your original post with php-imap, it seems like that's just another array issue as well. $mailsIds[1] gives you the second item in the array (not the first, array starts at 0). If you want to loop through them all, you need to do something like:

foreach ($mailsIds as $id) {
    $mail = $mailbox->getMail($id);
    dump($mail);
}

You may want to read up on how arrays work. These problems will be present regardless of which package you use.

GrahamMorbyDev's avatar

I think i was confusing how I return the data cause the app is using Vue on the front end and using axios requests to get the response

Simply couldn't see the wood from the trees!

Please or to participate in this conversation.