I am using PHP imap_search to fetch list of unseen messages since a given date like this:
imap_search($stream, 'UNSEEN SINCE 20-Sep-2015');
This is working fine. However, I am periodically every few minutes checking for new emails and then storing the last check time in a session. I want to be able to run the imap_search with the UNSEEN SINCE date including time. But it just does not seem to work. I've tried:
imap_search($stream, 'UNSEEN SINCE 20-Sep-2015 12:35:03 +0000 (UTC)');
imap_search($stream, 'UNSEEN SINCE 20-Sep-2015 12:35:03 +0000');
imap_search($stream, 'UNSEEN SINCE 20-Sep-2015 12:35:03');
Nothing seems to work. Any ideas if this can be done?
I don't think it's possible using php and the IMAP protocol. It seems that IMAP has a WITHIN Search Extension defined in rfc 5032, but it looks like php doesn't have this criteria yet. Also the SINCE criteria (and basically all the datetime criteria in the IMAP protocol) just ignores the time and timezone when you do a search operation. A workaround could be to get the emails with your current query, and then get the internal date and implementing the filter function with php datetime functions. Hope this helps. More info about IMAP: rfc 3501
You cannot achieve that with "SINCE"
Another way to do this is to remember the UID of the latest message you've seen, and then search for messages above that: (thanks to @legoscia)
According to http://php.net/manual/en/function.imap-search.php
$emails = imap_search($inbox, "UID 1:*", SE_UID);
is not valid, it is not working. Use
$emails = imap_fetch_overview($inbox, "$latest_uid:*", FT_UID);
Here * refers to the latest mail UID. This will return an array of objects from which you can extract the UIDs of emails. You can use a loop to make an array of the UIDs separately. As answered at PHP imap_search UID SEARCH returns false
Looking at the definition of SINCE
in RFC 3501:
SINCE <date>
Messages whose internal date (disregarding time and timezone)
is within or later than the specified date.
And a date
is defined as just a date, without a time:
date = date-text / DQUOTE date-text DQUOTE
date-day = 1*2DIGIT
; Day of month
date-month = "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" /
"Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec"
date-text = date-day "-" date-month "-" date-year
date-year = 4DIGIT
So you can't use SINCE
to search for messages based on a time more specific than a day.
Another way to do this is to remember the UID of the latest message you've seen, and then search for messages above that:
imap_search($stream, 'UID ' . $latest_uid . ':*', SE_UID);
The SE_UID
option is required to make imap_search
return UIDs instead of message sequence numbers.
To get the UID of the latest message in the first place, search for *
, which represents the highest-numbered message in the mailbox:
imap_search($stream, 'UID *', SE_UID);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With