PHP imap_reopen 没有返回错误

标签 php imap

我有一个连接到邮箱的脚本。 我想检查是否可以连接到不存在的文件夹,但 imap_reopen 不会返回错误。

<?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";
}

?>

脚本输出:

{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

你有什么想法吗?

问候,

斯蒂蒂

最佳答案

您的声明以 or die() 结尾实际上是在 if 之前终止执行针对 $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";
}

所以只需删除 or die()表达和你的if ($test == false)将被评估。我还将使用 ===这里因为它应该返回一个真正的 bool 值:

// Call imap_reopen() without (or die())
$test = imap_reopen($mbox, $imap_url . "INBOX.MBOX3");
if ($test === false) {
    echo "Opening submbox failed\n";
}

您也可以使用

if (!$test) {
    echo "Opening submbox failed\n";
}

关于发出的 PHP E_NOTICE 的注意事项 - if imap_reopen()即使返回 false 也会发出该通知,这是您可能想要使用 @ 的一个实例。运算符用于错误抑制,因为您正在正确测试 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() 其返回值是薄弱且含糊的:

Returns TRUE if the stream is reopened, FALSE otherwise.

一些测试似乎暗示打开不存在的邮箱不会被视为错误状态,它会返回 false 。在其他有效的流上打开不存在的邮箱时,imap_reopen()仍会返回true但在 imap_errors() 中填充错误.

所以你可以检查count(imap_errors()) > 0打开故障邮箱后出现错误。将其与 true 结合起来返回支票,以防万一imap_reopen()确实返回一个真正的错误状态。

例如,我的测试产生类似于以下内容的结果:

$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"
}

您可以使用逻辑来解决此问题:

$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
}

无论如何,imap_open()表现出相同的行为。使用不存在的邮箱可以成功连接和建立流(您的变量 $mbox )。流已创建且有效,但 imap_errors()将包含一条消息 Mailbox doesn't exist: <mailbox> .

关于PHP imap_reopen 没有返回错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29432904/

相关文章:

php - 如何在MT940中查找双重交易

php - 通过表单 POST 上传文件时注入(inject)文件路径

php - Laravel - 符号链接(symbolic link)公用文件夹

java mail api, imap 文件夹 UIDNEXT 总是-1

php - imap 电子邮件解析的编码

php - Symfony2/Doctrine 找不到自定义存储库类的映射文件

java - 如何解析 JavaMail api 上的签名?

python - 使用python计算电子邮件帐户中的邮件数量

c# - 使用 MailKit 检查 imap 文件夹是否存在

php - 自定义组件的Joomla后端组件文件上传