This lets you read a Pop3 email box and parse the resulting emails into a nested array. I'm sure it could be better, and it could be written into a class, but it suited my needs at the time and I learned a bit about POP3.

I believe the POP3 class that my functions use is licensed under the "artistic license" (this was new to me) and I am copyrighting my code under the GPL.

<?php
/****************************************************************************\
* PopParser functions                                                        *
* Authors: Aerik Sylvan (asylvan [at] gmail [dot] com)                       *
* License:  http://www.gnu.org/licenses/gpl.txt (GPL)                        *
******************************************************************************
* This is free software; you can redistribute it and/or modify it under      *
* the terms of the GNU General Public License as published by the            *
* Free Software Foundation; either version 2 of the License, or (at          *  
* your option) any later version.                                            *
*                                                                            *
* This software is distributed in the hope that it will be useful,           *
* but WITHOUT ANY WARRANTY; without even the implied warranty of             *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
* GNU General Public License for more details.                               *
*                                                                            *
* You should have received a copy of the GNU General Public License          *
* along with this program; if not, write to the Free Software                *
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA *
\****************************************************************************/

function getmsgbody($mbodyary){
    if(
is_array($mbodyary)){
        foreach (
$mbodyary as $section){
            
$sectype substr($section['header']['Content-Type'],0,9);
            if(
$sectype == 'text/plai'){
                
$mtext $section['text'];
            } elseif (
$sectype == 'text/html'){
                
$mhtml $section['text'];
            }
//elseif            
        
}//foreach
        
if(isset($mtext)){
            return 
$mtext;
        } elseif(isset(
$mhtml)){
            return 
strip_tags($mhtml);
        }
    } else {
    
//it must just be a string...
        
return $mbodyary;
    }
}

function 
get_msgAry(){
    
$mailserver "mail.yourhost.com";
    
$mailport 110;
    
$login 'yourlogin@yourhost.com';
    
$pass 'yourpassword';
        
    
$pop3 = new POP3();

    if(!
$pop3->connect($mailserver,$mailport))
    {
        echo 
"Ooops $pop3->ERROR <BR>\n";
            
//exit;
        
return false;
    }

    
$Count $pop3->login($login,$pass);
    if( (!
$Count) or ($Count == -1) )
    {
        
//echo "<H1>Login Failed: $pop3->ERROR</H1>\n";
        //exit;
        
return false;
    }

    
// ONLY USE THIS IF YOUR PHP VERSION SUPPORTS IT!
    //register_shutdown_function($pop3->quit());
    
    
$i=1;
    while(
$i<=$Count){
        
$MsgOne=($pop3->get($i));
        if( (!
$MsgOne) or (gettype($MsgOne) != "array") ){
            echo 
"oops, $pop3->ERROR<BR>\n";
            
//exit;
            
return false;
        } else {
            
//delete messages    
            
if(!$pop3->delete($i)) {
                echo 
"oops $pop3->ERROR - could not delete message<BR>\n";
                
//$pop3->reset();
            
}
            
$msgAry[]=split_msg($MsgOne);
        }
        
$i++;
    }    
    
$pop3->quit();
    return 
$msgAry;
}
//function

/*Helper function to split messages into header, body, and body parts.
            Like this:
            Header=> Array
                attr[name]=>value
                attr[name2]=>value2
            Body=> Array
                Bodypart[0]=>Array
                    Bodypart[0][bodyheader]=Array
                        Bodypart[0][bodyheader][name1]=value1
                        Bodypart[0][bodyheader][name2]=value2
                    Bodypart[0][text]=this is the text of the body
                Bodypart[1]=>Array
                    Etc
            */
function split_msg($rawmsg){
    
$headerflag true;
    
$hi 0;//index variable for header
    
$bi 0;//index var for body
    
    
if(is_array($rawmsg)){
        foreach(
$rawmsg as $mline){
            if(
$headerflag == true){
                if(
$mline =="\r\n"){
                    
$headerflag false;
                } else {
                    
$cloc strpos($mline,': ');
                    if (
$cloc === false){
                    
//belongs on previous header item - key is still the last value
                        
$msg['header'][$key].=$mline;
                        if(
$key =='Content-Type' && strpos($mline,'boundary="') !== false){
                            
preg_match('/boundary="([^"]*)"/',$mline,$matches);
                            
$msg['header']['_boundary'] = $matches[1];
                        }
//elseif            
                    
} else {
                        
$key substr($mline,0,$cloc);
                        
$value substr($mline,$cloc+2);
                        
$msg['header'][$key]=$value;
                        
// Special code to accomodate UTF-8 subject lines
                        
if($key == "Subject"){
                            
//Check for UTF-8 encoding - decode if found (need to translate to Latin-1?)
                            
if(strpos($value,"=?utf-8?B?") === 0){
                                
$encstr=substr($value,10,strlen($value)-14);
                                
$msg['header'][$key]=base64_decode($encstr);
                                
$msg['header']['encstr']=$encstr;
                                
$msg['header']['oldsubject']=$value;
                            }
//if
                        
}
                    }
                }
//else
            
} else {
                
//Must be in the body of the message...
                //$msg['body'].=$mline;//temporary
                
$body .=$mline;
            }
//else
        
}//foreach
        //Now check for multipart
        
if(isset($msg['header']['_boundary'])){
            
$body str_replace('--'.$msg['header']['_boundary']."--\r\n",'',$body);
            
$temp explode('--'.$msg['header']['_boundary']."\r\n",$body);
            
//print("Temp: ".count($temp)."<br />\n");
            
foreach($temp as $secnum=>$bsection){
                
//print "SECTION $secnum</br />\n";
                
$bheaderflag true;
                
$key false;
                if(
$bsection != ''){
                    
$templines explode("\r\n",$bsection);
                    foreach(
$templines as $tline){
                        
//print "<i>$tline</i><br />\n";
                        
if($bheaderflag){
                            
                            if(
$tline ==''){
                                
$bheaderflag false;
                            } else {
                                
$cloc strpos($tline,': ');
                                if (
$cloc === false){
                                
//belongs on previous header item - key is still the last value
                                    
if($key){
                                        
$msg['body'][$secnum]['header'][$key].=$tline;
                                    } else {
                                        
$msg['body'][$secnum]['header'].=$tline;
                                    }
                                } else {
                                    
$key substr($tline,0,$cloc);
                                    
$value substr($tline,$cloc+2);
                                    
$msg['body'][$secnum]['header'][$key]=$value;
                                }
                            }
                        } else {
                            
// add lines + add "\r\n" back in?
                            
$msg['body'][$secnum]['text'] .= $tline."\r\n";
                        }
//else
                    
}//foreach
                
}//if
                //$msg['body'][]=$bsection;
            
}//foreach
        
} else {
            
$msg['body'] = $body;
        }
        return 
$msg;
    } else {
        return 
false;
    }
//else 
}

function 
split_headers($rawmsg){
    
$headerflag true;
    
$hi 0;//index variable for header
    
$bi 0;//index var for body
    
    
if(is_array($rawmsg)){
        foreach(
$rawmsg as $mline){
            if(
$headerflag == true){
                if(
$mline =="\r\n"){
                    
$headerflag false;
                } else {
                    
$cloc strpos($mline,': ');
                    if (
$cloc === false){
                    
//belongs on previous header item - key is still the last value
                        
$msg['header'][$key].=$mline;
                        if(
$key =='Content-Type' && strpos($mline,'boundary="') !== false){
                            
preg_match('/boundary="([^"]*)"/',$mline,$matches);
                            
$msg['header']['_boundary'] = $matches[1];
                        }
//elseif            
                    
} else {
                        
$key substr($mline,0,$cloc);
                        
$value substr($mline,$cloc+2);
                        
$msg['header'][$key]=$value;
                        
// Special code to accomodate UTF-8 subject lines
                        
if($key == "Subject"){
                            
//Check for UTF-8 encoding - decode if found (need to translate to Latin-1?)
                            
if(strpos($value,"=?utf-8?B?") === 0){
                                
$encstr=substr($value,10,strlen($value)-14);
                                
$msg['header'][$key]=base64_decode($encstr);
                                
$msg['header']['encstr']=$encstr;
                                
$msg['header']['oldsubject']=$value;
                            }
//if
                        
}
                    }
                }
//else
            
} else {
                
//Must be in the body of the message...
                //$msg['body'].=$mline;//temporary
                
$body .=$mline;
            }
//else
        
}//foreach
        //rest of message...
        
$msg['body'] = $body;
        return 
$msg;
    } else {
        return 
false;
    }
//else
}


/*

    class.POP3.php3 v1.0    99/03/24 CDI cdi@thewebmasters.net
    Copyright (c) 1999 - CDI (cdi@thewebmasters.net) All Rights Reserved

    An RFC 1939 compliant wrapper class for the POP3 protocol.
*/

class POP3
{
    var 
$ERROR        "";        //    Error string.

    
var $TIMEOUT    60;        //    Default timeout before giving up on a
                                //    network operation.

    
var $COUNT        = -1;        //    Mailbox msg count

    
var $BUFFER        512;        //    Socket buffer for socket fgets() calls.
                                //    Per RFC 1939 the returned line a POP3
                                //    server can send is 512 bytes.

    
var $FP            "";        //    The connection to the server's
                                //    file descriptor

    
var $MAILSERVER    "";        // Set this to hard code the server name

    
var $DEBUG        false;    // set to true to echo pop3
                                // commands and responses to error_log
                                // this WILL log passwords!

    
var $BANNER        "";        //    Holds the banner returned by the
                                //    pop server - used for apop()

    
var $RFC1939    true;        //    Set by noop(). See rfc1939.txt    
                                //

    
var $ALLOWAPOP    false;    //    Allow or disallow apop()
                                //    This must be set to true
                                //    manually.

    
function POP3 $server ""$timeout "" )
    {
        
settype($this->BUFFER,"integer");
        if(!empty(
$server))
        {
            
// Do not allow programs to alter MAILSERVER
            // if it is already specified. They can get around
            // this if they -really- want to, so don't count on it.
            
if(empty($this->MAILSERVER))
            {
                
$this->MAILSERVER $server;
            }
        }
        if(!empty(
$timeout))
        {
            
settype($timeout,"integer");
            
$this->TIMEOUT $timeout;
            
set_time_limit($timeout);
        }
        return 
true;
    }

    function 
update_timer ()
    {
        
set_time_limit($this->TIMEOUT);
        return 
true;
    }

    function 
connect ($server$port 110)
    {
        
//    Opens a socket to the specified server. Unless overridden,
        //    port defaults to 110. Returns true on success, false on fail

        // If MAILSERVER is set, override $server with it's value

        
if(!empty($this->MAILSERVER))
        {
            
$server $this->MAILSERVER;
        }

        if(empty(
$server))
        {
            
$this->ERROR "POP3 connect: No server specified";  
            unset(
$this->FP);
            return 
false;
        }

        
$fp fsockopen("$server"$port, &$errno, &$errstr);

        if(!
$fp)
        {
            
$this->ERROR "POP3 connect: Error [$errno] [$errstr]";
            unset(
$this->FP);
            return 
false;
        }

        
set_socket_blocking($fp,-1);
        
$this->update_timer();
        
$reply fgets($fp,$this->BUFFER);
        
$reply $this->strip_clf($reply);
        if(
$this->DEBUG) { error_log("POP3 SEND [connect: $server] GOT [$reply]",0); }
        if(!
$this->is_ok($reply))
        {
            
$this->ERROR "POP3 connect: Error [$reply]";
            unset(
$this->FP);
            return 
false;
        }
        
$this->FP $fp;
        
$this->BANNER $this->parse_banner($reply);
        
$this->RFC1939 $this->noop();
        if(
$this->RFC1939)
        {
            
$this->ERROR "POP3: premature NOOP OK, NOT an RFC 1939 Compliant server";
            
$this->quit();
            return 
false;
        }
        return 
true;
    }

    function 
noop ()
    {
        if(!isset(
$this->FP))
        {
            
$this->ERROR "POP3 noop: No connection to server";
            return 
false;
        }
        
$cmd "NOOP";
        
$reply $this->send_cmd($cmd);
        if(!
$this->is_ok($reply))
        {
            return 
false;
        }
        return 
true;
    }

    function 
user ($user "")
    {
        
// Sends the USER command, returns true or false

        
if(empty($user))
        {
            
$this->ERROR "POP3 user: no user id submitted";
            return 
false;
        }
        if(!isset(
$this->FP))
        {
            
$this->ERROR "POP3 user: connection not established";
            return 
false;
        }
        
$reply $this->send_cmd("USER $user");
        if(!
$this->is_ok($reply))
        {
            
$this->ERROR "POP3 user: Error [$reply]";
            return 
false;
        }
        return 
true;
    }

    function 
pass ($pass "")
    {
        
// Sends the PASS command, returns # of msgs in mailbox,
        // returns false (undef) on Auth failure

        
if(empty($pass))
        {
            
$this->ERROR "POP3 pass: no password submitted";
            return 
false;
        }
        if(!isset(
$this->FP))
        {
            
$this->ERROR "POP3 pass: connection not established";
            return 
false;
        }
        
$reply $this->send_cmd("PASS $pass");
        if(!
$this->is_ok($reply))
        {
            
$this->ERROR "POP3 pass: authentication failed [$reply]";
            
$this->quit();
            return 
false;
        }
        
//    Auth successful.
        
$count $this->last("count");
        
$this->COUNT $count;
        
$this->RFC1939 $this->noop();
        if(!
$this->RFC1939)
        {
            
$this->ERROR "POP3 pass: NOOP failed. Server not RFC 1939 compliant";
            
$this->quit();
            return 
false;
        }
        return 
$count;
    }

    function 
apop ($login,$pass)
    {
        
//    Attempts an APOP login. If this fails, it'll
        //    try a standard login. YOUR SERVER MUST SUPPORT
        //    THE USE OF THE APOP COMMAND!
        //    (apop is optional per rfc1939)

        
if(!isset($this->FP))
        {
            
$this->ERROR "POP3 apop: No connection to server";
            return 
false;
        }

        if(!
$this->ALLOWAPOP)
        {
            
$retVal $this->login($login,$pass);
            return 
$retVal;
        }

        if(empty(
$login))
        {
            
$this->ERROR "POP3 apop: No login ID submitted";
            return 
false;
        }
        if(empty(
$pass))
        {
            
$this->ERROR "POP3 apop: No password submitted";
            return 
false;
        }
        
$banner $this->BANNER;
        if( (!
$banner) or (empty($banner)) )
        {
            
$this->ERROR "POP3 apop: No server banner - aborted";
            
$retVal $this->login($login,$pass);
            return 
$retVal;
        }
        
$AuthString $banner;
        
$AuthString .= $pass;
        
$APOPString md5($AuthString);
        
$cmd "APOP $login $APOPString";
        
$reply $this->send_cmd($cmd);
        if(!
$this->is_ok($reply))
        {
            
$this->ERROR "POP3 apop: apop authentication failed - abort";
            
$retVal $this->login($login,$pass);
            return 
$retVal;
        }
        
//    Auth successful.
        
$count $this->last("count");
        
$this->COUNT $count;
        
$this->RFC1939 $this->noop();
        if(!
$this->RFC1939)
        {
            
$this->ERROR "POP3 apop: NOOP failed. Server not RFC 1939 compliant";
            
$this->quit();
            return 
false;
        }
        return 
$count;
    }

    function 
login ($login ""$pass "")
    {
        
// Sends both user and pass. Returns # of msgs in mailbox or
        // false on failure (or -1, if the error occurs while getting
        // the number of messages.)

        
if(!isset($this->FP))
        {
            
$this->ERROR "POP3 login: No connection to server";
            return 
false;
        }
        
$fp $this->FP;
        if(!
$this->user($login))
        {
            
//    Preserve the error generated by user()
            
return false;
        }
        
$count $this->pass($pass);
        if( (!
$count) or ($count == -1) )
        {
            
//    Preserve the error generated by last() and pass()
            
return false;
        }
        return 
$count;
    }

    function 
top ($msgNum$numLines "0")
    {
        
//    Gets the header and first $numLines of the msg body
        //    returns data in an array with each returned line being
        //    an array element. If $numLines is empty, returns
        //    only the header information, and none of the body.

        
if(!isset($this->FP))
        {
            
$this->ERROR "POP3 top: No connection to server";
            return 
false;
        }
        
$this->update_timer();

        
$fp $this->FP;
        
$buffer $this->BUFFER;
        
$cmd "TOP $msgNum $numLines";
        
fwrite($fp"TOP $msgNum $numLines\r\n");
        
$reply fgets($fp$buffer);
        
$reply $this->strip_clf($reply);
        if(
$this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); }
        if(!
$this->is_ok($reply))
        {
            
$this->ERROR "POP3 top: Error [$reply]";
            return 
false;
        }

        
$count 0;
        
$MsgArray = array();

        
$line fgets($fp,$buffer);
        while ( !
ereg("^\.\r\n",$line))
        {
            
$MsgArray[$count] = $line;
            
$count++;
            
$line fgets($fp,$buffer);
            if(empty(
$line))    { break; }
        }

        return 
$MsgArray;
    }

    function 
pop_list ($msgNum "")
    {
        
//    If called with an argument, returns that msgs' size in octets
        //    No argument returns an associative array of undeleted 
        //    msg numbers and their sizes in octets

        
if(!isset($this->FP))
        {
            
$this->ERROR "POP3 pop_list: No connection to server";
            return 
false;
        }
        
$fp $this->FP;
        
$Total $this->COUNT;
        if( (!
$Total) or ($Total == -1) )
        {
            return 
false;
        }
        if(
$Total == 0)
        {
            return array(
"0","0");
            
// return -1;    // mailbox empty
        
}

        
$this->update_timer();

        if(!empty(
$msgNum))
        {
            
$cmd "LIST $msgNum";
            
fwrite($fp,"$cmd\r\n");
            
$reply fgets($fp,$this->BUFFER);
            
$reply $this->strip_clf($reply);
            if(
$this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); }
            if(!
$this->is_ok($reply))
            {
                
$this->ERROR "POP3 pop_list: Error [$reply]";
                return 
false;
            }
            list(
$junk,$num,$size) = explode(" ",$reply);
            return 
$size;
        }
        
$cmd "LIST";
        
$reply $this->send_cmd($cmd);
        if(!
$this->is_ok($reply))
        {
            
$reply $this->strip_clf($reply);
            
$this->ERROR "POP3 pop_list: Error [$reply]";
            return 
false;
        }
        
$MsgArray = array();
        
$MsgArray[0] = $Total;
        for(
$msgC=1;$msgC <= $Total$msgC++)
        {
            if(
$msgC $Total