• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • imap_open()

    (PHP 4, PHP 5, PHP 7)

    Open an IMAP stream to a mailbox

    说明

    imap_open(string $mailbox,string $username,string $password[,int $options= 0[,int $n_retries= 0[,array $params= array()]]]): resource

    Opens an IMAP stream to a$mailbox.

    This function can also be used to open streams to POP3 and NNTP servers, but some functions and features are only available on IMAP servers.

    参数

    $mailbox

    A mailbox name consists of a server and a mailbox path on this server. The special nameINBOXstands for the current users personal mailbox. Mailbox names that contain international characters besides those in the printable ASCII space have to be encoded with imap_utf7_encode().

    Warning

    Passing untrusted data to this parameter isinsecure, unlessimap.enable_insecure_rsh is disabled.

    The server part, which is enclosed in '{' and '}', consists of the servers name or ip address, an optional port(prefixed by ':'), and an optional protocol specification(prefixed by '/').

    The server part is mandatory in all mailbox parameters.

    All names which start with{are remote names, and are in the form"{" remote_system_name[":" port][flags]"}"[mailbox_name]where:

    • remote_system_name- Internet domain name or bracketed IP address of server.
    • port- optional TCP port number, default is the default port for that service
    • flags- optional flags, see following table.
    • mailbox_name- remote mailbox name, default is INBOX
    Optional flags for names
    FlagDescription
    /service=servicemailbox access service, default is "imap"
    /user=userremote user name for login on the server
    /authuser=userremote authentication user; if specified this is the user name whose password is used(e.g. administrator)
    /anonymousremote access as anonymous user
    /debugrecord protocol telemetry in application's debug log
    /securedo not transmit a plaintext password over the network
    /imap,/imap2,/imap2bis,/imap4,/imap4rev1equivalent to/service=imap
    /pop3equivalent to/service=pop3
    /nntpequivalent to/service=nntp
    /norshdo not use rsh or ssh to establish a preauthenticated IMAP session
    /ssluse theSecure Socket Layerto encrypt the session
    /validate-certvalidate certificates from TLS/SSL server(this is the default behavior)
    /novalidate-certdo not validate certificates from TLS/SSL server, needed if server uses self-signed certificates
    /tlsforce use ofstart-TLSto encrypt the session, and reject connection to servers that do not support it
    /notlsdo not dostart-TLSto encrypt the session, even with servers that support it
    /readonlyrequest read-only mailbox open(IMAP only; ignored on NNTP, and an error with SMTP and POP3)
    $username

    The user name

    $password

    The password associated with the$username

    $options

    The$optionsare a bit mask with one or more of the following:

    • OP_READONLY- Open mailbox read-only
    • OP_ANONYMOUS- Don't use or update a.newsrcfor news(NNTP only)
    • OP_HALFOPEN- For IMAP and NNTP names, open a connection but don't open a mailbox.
    • CL_EXPUNGE- Expunge mailbox automatically upon mailbox close(see also imap_delete() and imap_expunge())
    • OP_DEBUG- Debug protocol negotiations
    • OP_SHORTCACHE- Short(elt-only)caching
    • OP_SILENT- Don't pass up events(internal use)
    • OP_PROTOTYPE- Return driver prototype
    • OP_SECURE- Don't do non-secure authentication
    $n_retries

    Number of maximum connect attempts

    $params

    Connection parameters, the following(string)keys maybe used to set one or more connection parameters:

    • DISABLE_AUTHENTICATOR- Disable authentication properties

    返回值

    Returns an IMAP stream on success or FALSE on error.

    更新日志

    版本说明
    5.3.2$paramsadded
    5.2.0$n_retriesadded

    范例

    Example #1 Different use of imap_open()

    <?php
    // To connect to an IMAP server running on port 143 on the local machine,
    // do the following:
    $mbox = imap_open("{localhost:143}INBOX", "user_id", "password");
    // To connect to a POP3 server on port 110 on the local server, use:
    $mbox = imap_open ("{localhost:110/pop3}INBOX", "user_id", "password");
    // To connect to an SSL IMAP or POP3 server, add /ssl after the protocol
    // specification:
    $mbox = imap_open ("{localhost:993/imap/ssl}INBOX", "user_id", "password");
    // To connect to an SSL IMAP or POP3 server with a self-signed certificate,
    // add /ssl/novalidate-cert after the protocol specification:
    $mbox = imap_open ("{localhost:995/pop3/ssl/novalidate-cert}", "user_id", "password");
    // To connect to an NNTP server on port 119 on the local server, use:
    $nntp = imap_open ("{localhost:119/nntp}comp.test", "", "");
    // To connect to a remote server replace "localhost" with the name or the
    // IP address of the server you want to connect to.
    ?>
    

    Example #2 imap_open() example

    <?php
    $mbox = imap_open("{imap.example.org:143}", "username", "password");
    echo "<h1>Mailboxes</h1>\n";
    $folders = imap_listmailbox($mbox, "{imap.example.org:143}", "*");
    if ($folders == false) {
        echo "Call failed<br />\n";
    } else {
        foreach ($folders as $val) {
            echo $val . "<br />\n";
        }
    }
    echo "<h1>Headers in INBOX</h1>\n";
    $headers = imap_headers($mbox);
    if ($headers == false) {
        echo "Call failed<br />\n";
    } else {
        foreach ($headers as $val) {
            echo $val . "<br />\n";
        }
    }
    imap_close($mbox);
    ?>
    

    参见

    Do not bother using "/debug" flag in $mailbox or OP_DEBUG in $options. They do not do anything.
    When you set either one, the underlying IMAP c-client library will gather protocol debugging data and pass it back to PHP.
    However, the debug handler defined by PHP is an empty function, it doesn't do anything.
    So unless you're using a customized version of the IMAP extension that does something with that handler (mm_dlog), there is no point using "/debug" or OP_DEBUG.
    Using: 
    <?php
    imap_open( "{server.example.com:143}INBOX" , 'login' , 'password' );
    ?>
    Got this error:
    "Couldn't open stream {server.example.com:143}INBOX" 
    Solved by adding the flag "novalidate-cert":
    <?php
    imap_open( "{server.example.com:143/novalidate-cert}INBOX" , 'login' , 'password' );
    ?>
    =D
    None of the above comments explain the configuration issues on Apache/Windows combination. I thought it might be helpful to list my findings here so that Windows people's time is saved.
    There is a bug in Windows php_imap.dll that prevents it from connecting it to the SSL IMAP/POP3 server.
    http://bugs.php.net/bug.php?id=36496&edit=1
    One of the issues with gmail IMAP SSL authentication is related to Google's account security.
    Once you get the login error once, sign out of all your google accounts. Then, visit this link:
    http://www.google.com/accounts/DisplayUnlockCaptcha
    Log in with the account you're attempting to access via imap.
    Follow the steps and you'll then be able to login in to gmail with php imap.
    It's visually shown here:
    http://jeffreifman.com/filtered-open-source-imap-mail-filtering-software-for-php/configuring-gmail/
    imap_open is very simple to use, but struggles a litte bit on setups with ssl and tls.
    this are tested examples for different hosts and protocols.
    uncomment the host/protocol line and fill in correct username and password.
    Kay
    <?php
    #######
    # localhost pop3 with and without ssl
    # $authhost="{localhost:995/pop3/ssl/novalidate-cert}";
    # $authhost="{localhost:110/pop3/notls}";
    # localhost imap with and without ssl
    # $authhost="{localhost:993/imap/ssl/novalidate-cert}";
    # $authhost="{localhost:143/imap/notls}";
    # $user="localuser";
    # localhost nntp with and without ssl
    # you have to specify an existing group, control.cancel should exist
    # $authhost="{localhost:563/nntp/ssl/novalidate-cert}control.cancel";
    # $authhost="{localhost:119/nntp/notls}control.cancel";
    ######
    # web.de pop3 without ssl
    # $authhost="{pop3.web.de:110/pop3/notls}";
    # $user="kay.marquardt@web.de";
    #########
    # goggle with pop3 or imap
    # $authhost="{pop.gmail.com:995/pop3/ssl/novalidate-cert}";
    # $authhost="{imap.gmail.com:993/imap/ssl/novalidate-cert}";
    # $user="username@gmail.com";
    $user="username like above";
    $pass="yourpass";
    if ($mbox=imap_open( $authhost, $user, $pass ))
        {
         echo "<h1>Connected</h1>\n";
         imap_close($mbox);
        } else
        {
         echo "<h1>FAIL!</h1>\n";
        }
    ?>
    
    Subfolders of INBOX have to be seperate by dot like this: 'INBOX.test'
    $mailbox = '{example.example.com:143/imap/novalidate-cert}INBOX.test'
    imap_open will not open a stream if your server operates with Transport Layer Security (i.e. TLS) imap_open connects with SSL if its there. So try opening mailbox as 
    $mailbox="{mail.domain.com:143/imap/notls}"; 
    or
    $mailbox="{mail.domain.com:110/pop3/notls}"; This works...
    Some mail server requires you to provide username@domain.com so you can always use. user@doamin.com
    $conn=imap_open($mailbox, $username, $password);
    Some server may ask for username as "user=user@domain.com"
    :)
    This code demonstrates features that are not well documented at this time. The main feature is that the selected mailbox in imap_open (or reopen) and the specified mailbox in other imap functions are unrelated. It has been tested with Gmail and with a Dovecot IMAP server. The mailbox separator depends on the server. Gmail: "/" Dovecot: "." If you want to test with Gmail, you need to turn on "Access for less secure apps" in your account.
     
    <?php
     // Change these.
     $server  = "{imap.gmail.com:993/imap/ssl/novalidate-cert}"; 
     $email   = "example@gmail.com"; 
     $password = "password";
     
     // The code assumes that the folders Test/Sub1/Sub11, etc. exist. 
     $selected = "{$server}Test/Sub1/Sub12";
     $conn   = imap_open($selected, $email , $password);
     // This returns the $specified mailbox and its sub mailboxes, 
     // even if the $specified mailbox is outside the $selected mailbox. 
     $specified = "{$server}Test/Sub1"; 
     $boxes   = imap_list($conn, $specified , '*');
     print_r($boxes);
     
     // This appends the message in the $specified mailbox. 
     // It ignores the $selected mailbox. 
     imap_append($conn, $specified
               , "From: me@example.com\r\n"
               . "To: you@example.com\r\n"
               . "Subject: test\r\n"
               . "\r\n"
               . "this is a test message, please ignore\r\n");
     // This changes the $selected mailbox
     $selected = "{$server}Test/Sub1"; 
     imap_reopen($conn, $selected); 
     // This moves a message from the $selected to the $specified mailbox
     // In this case, the specified mailbox does not include the server. 
     imap_mail_move ($conn , "1" , "Test"); 
     imap_expunge($conn); 
     imap_close($conn);
     // If you executed this code with a real IMAP server, 
     // the message is now in the Test mailbox !
    ?>
    
    For all imap functions where you specify the mailbox string it is important that you ALWAYS use IP (not hostname) and the portnumber. If you do not do this imap functions will be painfully slow.
    Using hostname instead of IP adds 3 seconds to each IMAP call, not using portnumber adds 10 seconds to each imap call. (hint: use gethostbyname() )
    In order to make a IMAP connection to a Microsoft Exchange Server 5.5, I used this connection-string :
    <?php
    if(imap_open ("{192.168.1.6:143/imap}Inbox", "DOMAIN/USERNAME/ALIAS", "PASSWORD"))
    {
      echo 'Connection success!';
    }
    else
    {
      echo 'Connection failed';
    }
    ?>
    By replacing "Inbox" with, e.g. "Tasks", its possible to see all your tasks. I Hope this helps anybody!
    Regards
    You can do
    <? $foo = imap_errors(); ?>
    to clear unwanted warning messages like 'Mailbox is empty'
    Since Version 5.3.2 there's a 6th parameter available to disable authentication with GSSAPI or NTLM:
    Example:
    <?php
    $mbox = imap_open("{w2010ExchangeServer:993/imap/ssl}", $user, $password, NULL, 1, array('DISABLE_AUTHENTICATOR' => 'GSSAPI'));
    ?>
    This solves the problem with Exchange 2010 for me. As a reference see https://bugs.php.net/bug.php?id=33500
    My script kept on timing out, even though the syntax was spot on... ultimately, I figured out that the port was blocked by my webhost, where I ran this on a shared server...
    I post this just in case you miss this obvious, like I did.
    a little tip for those who get really frustrated even after reading all the right solutions and implementing them but still get the same errors or none at all..:
    after having changed the code.. restart the httpd deamon..
    for Fedora or any other Red Hat Linux OS (/etc/init.d/httpd restart).
    After this you will be able to make a imap/pop3 stream from apache..
    To authenticate using kerberos V / GSSAPI, you might need to add "user=" to the connection string.. eg:
    $mbox = imap_open( "\{imap.example.com:143/imap/notls/user=" . $user . "}INBOX", $user, $passwd );
    Our IMAP servers won't allow a user other than the user specified in the kerberos credentials connect using those credentials unless you specify that extra "user=" in the connection string. Passing it as an argument to imap_open() doesn't seem to be enough.
    I had been having lots of trouble trying to get imap_open to connect to an imap server. Then I found another post online that suggested this and it worked, so I am going to post it here. I hope this helps others..
    "I have tried with the following strings instead and it works: 
    for pop3: {www.server.com:110/pop3/notls}INBOX 
    and for imap: {www.server.com:143/notls}INBOX.
    On Windows, this function does not use certificates in directories listed by openssl_get_cert_locations(): it use system's certificates store. If you want to use a certificate signed by a test authority, you must add root certificate of your test authority to Window's certificates store.
    An old archived 2006 PHP script to retrieve IMAP POP3 email into a MySQL database and as files is at:
    http://web.archive.org/web/20060411020022/http://www.sellchain.com/phPOP3/phPOP3.txt
    The error: Unknown: Mailbox is empty (errflg=1) in Unknown on line 0
    appears when:
    1) use imap_open to connect 
    2) then use imap_search ALL to retrieve emails
    but there are no messages available. To avoid this error, check first the number of messages in a mailbox using imap_status. Only if there are messages available then you can use the imap_search.
    If you get Kerberos errors like:
    « Notice: Unknown: Kerberos error: Credentials cache file '/tmp/krb5cc_0123' not found (try running kinit) ».
    Try to add as a $param:
    <?php array('DISABLE_AUTHENTICATOR' => 'GSSAPI') ?>
    eg.
    <?php
    $imap_stream = imap_open('{mail.domain.tld:993/imap/ssl}' , 'username' , 'password', null, 1, array('DISABLE_AUTHENTICATOR' => 'GSSAPI'));
    ?>
    
    Function to test most of the possible options of a connection:
    function imapConfig($options, $i=0, $till = array()) {
        if(sizeof($options)==$i)
          return $till;
        
        if(sizeof($till)==0)
          $till[] = '';
        
        $opt = $options[$i];
        $new = array();
        foreach($till as $t) {
          foreach($opt as $o) {
            if(strlen($o)==0)
              $new[] = $t;
            else
              $new[] = $t.'/'.$o;
          }
        }
        return imapConfig($options, $i+1, $new);
      }
    function imap_test($server, $port, $dir, $username, $passw) {
        $options = array();
        //$options[] = array('debug');
        $options[] = array('imap', 'imap2', 'imap2bis', 'imap4', 'imap4rev1', 'pop3'); //nntp
        $options[] = array('', 'norsh');
        $options[] = array('', 'ssl');
        $options[] = array('', 'validate-cert', 'novalidate-cert');
        $options[] = array('', 'tls', 'notls');
        
        $configOptions = imapConfig($options);
        foreach($configOptions as $c) {
          $mbox = @imap_open("{".$server.":".$port.$c."}".$dir, $username, $passw);
          echo "<b>{".$server.":".$port.$c."}".$dir."</b> ... ";
          if (false !== $mbox) {
            echo '<span style="color:green"> success</span>';
          }
          else {
            echo '<span style="color:red"> failed</span>';
          }
          echo '<br>';
        }
      }
    imap_test('mail.server.de', 143, 'INBOX', 'username', 'pwd');
    If you get slow imap4/pop3 authentication step 
    i.e. 5-10 sec just for response, maybe you are connecting to an imap server which is advertising GSSAPI auth mechanism.
    Martin Eckardt note could help to speed it up.
    <?php
    $mbox = imap_open("{imap server with GSSAPI :993/imap/ssl}", $user, $password, NULL, 1, array('DISABLE_AUTHENTICATOR' => 'GSSAPI'));
    ?>
    Disable GSSAPI if you dont use it.
    If your imap/pop server is Dovecot
    /etc/dovecot/conf.d/10-auth.conf
    ...
    auth_mechanisms = plain login gssapi
    -> auth_mechanisms = plain login
    Hi
    I was struggling with the Gmail Imap/pop connection. It keeps saying too many failed login connections were made.
    Thing I did:
     https://www.google.com/settings/security/lesssecureapps
    Clicked "Turn on"
    > worked!
    So last step could be used but remember your account will be at a certain security risk. Anyway it comes in handy to develop...
    imap_open()
     validate SSL certificate does not support Subject Alternative Name (SAN) certificate. It only validate against the Subject/Common name.
    If you are accessing a local mailbox file, i.e. imap_open('/var/mail/www-data', '', ''), you may be restricted in what files you can access.
    If PHP IMAP was compiled with the restrictBox option (which I believe most packages are these days), you can only access files relative to $HOME. Paths starting with '/' or '../' will be rejected.
    If your connection is too slow, try it with port and without domain.
    <?php
    //Normal connection
    $mailbox = imap_open("{SERVER}INBOX", $username, $password);
    //Faster connection
    $mailbox = imap_open("{SERVER:143}INBOX", $username, $password);
    //Very slow connection
    $mailbox = imap_open ("{SERVER.DOMAIN}INBOX", "DOMAIN/".$username, $password);
    ?>
    
    I managed to use this function against Exchange 2010 without recompiling to disable kerberos
    It's important to me that php installs per the standard package (yum install php)
    Exchange 2010 triggers kerberos in php, and you require the kinit thing (search around google for "imap_open kinit exchange 2010" and you will find this)
    To get it working I had to:
    1. setup the krb5.conf file correctly
    2. do a kinit username@DOMAIN.DOM with a valid username / password
    3. rename the ticket file to reflect the user id of apache (usually 48)
      /tmp/krb5cc_48
    4. fix ownership
      chown apache.apache /tmp/krb5cc_48
    but the exchange server will use the kerberos ticket and not the username password - unless you use ssl
    <?php
      $imap_user = "username";
      $imap_pass = "password";
      $imap_server = "{w2010kExchangeServer:993/novalidate-cert/ssl}";
      $mbox = imap_open("{$imap_server}INBOX", $imap_user, $imap_pass);
      $sorted_mbox = imap_sort($mbox, SORTDATE, 0);
      $totalrows = imap_num_msg($mbox);
      print "$imap_server\n";
      $startvalue = 0;
      while ($startvalue < $totalrows) {
        $headers = imap_fetchheader($mbox, $sorted_mbox[ $startvalue ] );
        $subject = array();
        preg_match_all('/^Subject: (.*)/m', $headers, $subject);
        print $subject[1][0] . "\n";
        $startvalue++;
      }
    ?>
      
    One small step for php / exchange, one Giant leap for David ....
    "Couldn't open stream {127.0.0.1:143/imap/notls}INBOX" 
    Solved by only replacing 127.0.0.1 with localhost, php and IMAP server both in same machine, not through Proxy or anything. Weird!
    Make sure your PHP is enabled with imap via the phpinfo() function
    '--with-imap-dir=/opt/lampp' '--with-imap-ssl' '--with-imap=/opt/lampp'
    and 
    IMAP c-Client Version 2007e
    SSL Support Yes
    I noticed that my apache script was working but my cli script was not. Turns out my php cli executable didn't have imap setup so I had to use another php cli executable.
    Dears.
    In my case, e-mail host was the IMAP enabled.
    So, just use the imap_open as the very simple form like:
    $mailbox = "{mail.myhost.com:143/notls}INBOX";
    $user = "me@myhost.com"; 
    $pass = "mypassword"; 
    $connection = imap_open($mailbox,$user,$pass) or die(imap_last_error()."<br>Connection Faliure!");
    thanks!
    Works with Gmail's new IMAP function for personal and for Google Apps.
    $mbox = imap_open ("{imap.gmail.com:993/imap/ssl}INBOX", "username@gmail.com", "password")
       or die("can't connect: " . imap_last_error());
    By default, imap_open() will retry an incorrect password 3 times before giving up. This is a feature built into the c-client library intended for interactive mail clients (which can prompt the end user for a new username/password combo.)
    The new optional parameter "$n_retries" allows PHP to override the default retry limit. There is absolutely no reason to leave this at default, or to set it to any value other than 1. This is especially important if the mail server you're using locks users out after too many login failures.
    For FreeBSD users...
    If you want to have SSL support, you want to install the ports:
    mail/php5-imap
    security/php5-openssl
    Cheers :)
     - avizion
    Thanks for all your comments. The user comments have saved me countless times.
    I'd like to give back in my small way by providing this little tip. To test your pop or imap services you can use telnet (almost all operating systems should come with a command line telnet client).
    Here's the pop3 example (the lines that start with + are the server's response):
      telnet your.pop.host.com 110
      +OK POP3 your.pop.host.com v2001.78 server ready
      user your_username
      +OK User name accepted, password please
      pass your_password
      +OK Mailbox open, 23 messages
    Note that your pop server may be on some other port than 110 but that is the default/standard.
    Here's the imap example (Lines that have OK near the begining are server responses):
      telnet your.imap.host.com 143
      * OK [CAPABILITY IMAP4REV1...]
      1 LOGIN "your_username" "your_password"
      1 OK [CAPABILITY...] ... User your_username authenticated
    This might be old news to some people but I hope it's helpful for many.
    I have a single comment to add about imap_open.
    If you want to connect to a news server, without specifying any news gruop, you can use the following:
    <?php
    $server = "{news.servername.com/nntp:119}";
    $nntp = imap_open($server,"","",OP_HALFOPEN);
    ?>
    and $nntp will become the connection ID.
    Regards 
    //Babak
    I've found that on my servers I _must_ use imap_errors() and imap_alerts() after an imap_open or this error is thrown in the logs when the mailbox is empty: [error] PHP Warning: (null)(); Mailbox is empty (errflg=1) in Unknown on line 0

    上篇:imap_num_recent()

    下篇:imap_ping()