I have a script that connects to a mailbox.
I'd like to check if I can connect to a folder that does not exist, but imap_reopen
does not return errors.
<?php
$imap_url = "{mybox.mail.box:143}";
$mbox = imap_open($imap_url, "Mylogin", "Mypassword");
if ($mbox == false) {
echo "Opening mailbox failed\n";
}
$submbox = imap_listmailbox($mbox, $imap_url, "*");
if ($submbox == false) {
echo "Listing sub-mailboxes failed\n";
}
else {
foreach ($submbox as $name) {
echo $name . PHP_EOL;
}
}
$test = imap_reopen($mbox, $imap_url . "INBOX.MBOX3") or die(implode(", ", imap_errors()));
if ($test == false) {
echo "Opening submbox failed\n";
}
?>
Script output :
{mybox.mail.box:143}.INBOX
{mybox.mail.box:143}.INBOX.MBOX1
{mybox.mail.box:143}.INBOX.MBOX2
PHP Notice: Unknown: Mailbox does not exist (errflg=2) in Unknown on line 0
Do you have an idea ?
Regards,
Stiti
Your statement ending with or die()
is actually terminating execution before the if
test against the return value in $test
.
$test = imap_reopen($mbox, $imap_url . "INBOX.MBOX3") or die(implode(", ", imap_errors()));
// This code is never reached because of die()!
if ($test == false) {
echo "Opening submbox failed\n";
}
So just remove the or die()
expression and your if ($test == false)
will be evaluated. I'll also use ===
here since it should return a true boolean:
// Call imap_reopen() without (or die())
$test = imap_reopen($mbox, $imap_url . "INBOX.MBOX3");
if ($test === false) {
echo "Opening submbox failed\n";
}
You may alternatively use
if (!$test) {
echo "Opening submbox failed\n";
}
Note about the PHP E_NOTICE emitted - if imap_reopen()
emits that notice even when returning false
, this is one instance in which you may want to use the @
operator for error suppression since you are correctly testing for errors in your if
block.
// @ is not usually recommended but if imap_reopen()
// prints an E_NOTICE while still returning false you can
// suppress it with @. This is among the only times it's
// a good idea to use @ for error suppresssion
$test = @imap_reopen($mbox, $imap_url . "INBOX.MBOX3");
if (!$test) {...}
Documentation on imap_reopen()
is slim and ambiguous stating its return as:
Returns TRUE if the stream is reopened, FALSE otherwise.
Some testing seems to imply that opening a non-existent mailbox is not considered an error state for which it returns false
. When opening a non-existent mailbox on an otherwise valid stream, imap_reopen()
will still return true
but populate an error in imap_errors()
.
So you may check count(imap_errors()) > 0
for errors after opening the faulty mailbox. Couple that with a true
return check, in case imap_reopen()
does return a true error state.
For example my testing produces results similar to:
$test = imap_reopen($mbox, $imap_url . "NOTEXIST");
var_dump($test);
// bool(true);
var_dump(imap_errors()); array(1) {
[0] =>
string(28) "Mailbox doesn't exist: NOTEXIST"
}
You may work around this using logic to:
$test = @imap_reopen($mbox, $imap_url . "INBOX.MBOX3");
if (!$test) {
// An error with the stream
}
// Returns true, but imap_errors() is populated
else if ($test && count(imap_errors()) > 0) {
echo "Opening submbox failed\n";
// Do something with imap_errors() if needed
echo implode(',', imap_errors());
}
else {
// Everything is fine - the mailbox was opened
}
For what it's worth, imap_open()
exhibits the same behavior. Successfully connecting and establishing the stream (your variable $mbox
) is possible with a non-existent mailbox. The stream is created and valid, but imap_errors()
will contain a message Mailbox doesn't exist: <mailbox>
.