[PHP] Communiceren met IMAP middels PHP

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • MarkvE
  • Registratie: Maart 2004
  • Laatst online: 30-01 17:16
Ik zou graag willen leren hoe je via PHP kunt communiceren met een IMAP server (omdat ik de PHP functies van de IMAP module maar erg beperkt vindt en meer zelf in de hand zou willen hebben). Nu heb ik via imap.org de RFC (3501) kunnen lezen, maar deze vindt ik erg beknopt en daardoor lukken de meeste probeelsels met commands nog niet.

Om een voorbeeldje te noemen, verder dan dit ben ik nog niet gekomen (behalve een paar andere simpele enkelvoudige commands zoals NOOP):

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
if ( $connection = fsockopen ( 'localhost', 143 ) )
{
    echo '<pre>';
    echo fgets($connection, 1024) . "\r\n";
    fputs($connection, "a001 LOGIN gebruikersnaam wachtwoord\r\n");
    echo fgets($connection, 1024) . "\r\n";
    fputs($connection, "a002 STATUS INBOX (MESSAGES UNSEEN)\r\n");
    echo fgets($connection, 1024) . "\r\n";
    fputs($connection, "a003 LOGOUT\r\n");
    echo fgets($connection, 1024) . "\r\n";
    echo '</pre>';
    
    fclose ( $connection );
}


En wat mij bijvoorbeeld niet lukt, maar wel hier staat beschreven is:
a04 FETCH 1:* FLAGS
Hiermee krijg ik een error terug van de IMAP server, betekenend dat het command niet juist is. Terwijl deze het volgens mij toch zou moeten doen.

Tevens is mij opgevallen dat op de link de respons van de server veel uitgebreider is dan ik die terug krijg van mijn server.

Wie kan mij de helpende hand toedienen in welke vorm dan ook?

Bij voorbaad dank!

[ Voor 9% gewijzigd door MarkvE op 07-10-2004 13:29 ]

Vormkracht10


Acties:
  • 0 Henk 'm!

  • Arjan A
  • Registratie: November 2000
  • Laatst online: 12:24

Arjan A

Cenosillicafoob

Als je meer wil terugkrijgen dan 1024 tekens, kijk dan eens op http://nl.php.net/fgets

PHP:
1
2
3
4
while (!feof($handle)) {
   $buffer = fgets($handle, 4096);
   echo $buffer;
}

Het gaat niet of die 1024 veranderd is naar 4096, maar om de while-lus, die door blijft gaan tot $handle geheel is uitgelezen.

Canon EOS | DJI M2P
Fotoblog · Mijn werk aan jouw muur


Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 14:28
omdat ik de PHP functies van de IMAP module maar erg beperkt vindt en meer zelf in de hand zou willen hebben).
Wat heb je dan als beperking gevonden?

Acties:
  • 0 Henk 'm!

  • MarkvE
  • Registratie: Maart 2004
  • Laatst online: 30-01 17:16
Arjan A schreef op 07 oktober 2004 @ 14:23:
Als je meer wil terugkrijgen dan 1024 tekens, kijk dan eens op http://nl.php.net/fgets

PHP:
1
2
3
4
while (!feof($handle)) {
   $buffer = fgets($handle, 4096);
   echo $buffer;
}

Het gaat niet of die 1024 veranderd is naar 4096, maar om de while-lus, die door blijft gaan tot $handle geheel is uitgelezen.
Het ligt daar in ieder geval niet aan, dat de respons minder uitgebreid was.
djluc schreef op 07 oktober 2004 @ 16:09:
[...]
Wat heb je dan als beperking gevonden?
Bijvoorbeeld bij de headers, wanneer je een header wilt hebben die niet tussen de specificaties van imap_headerinfo staat, dan moet je dat uit imap_fetchheader halen en dan zelf de headers door spitten. Dan kun je dat beter gewoon helemaal zelf doen (dus de headers opvragen, parsen).

Tevens krijg je bij veel functies irritante objecten terug die je dan zelf weer kunt omzetten naar bewerkbare array's. En ik trek de snelheid van de functies van IMAP in twijfel.

Daarnaast is de IMAP module in PHP overbodig (en kan het dus op elke sever draaien) als je direct met de server communiceert.

[ Voor 32% gewijzigd door MarkvE op 07-10-2004 17:32 ]

Vormkracht10


Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 14:28
Ok, je mening is duidelijk. Wat voor je sowieso interessant is om door te nemen: de source van Squirrelmail. Deze werkt ook zonder de module.

Acties:
  • 0 Henk 'm!

  • MarkvE
  • Registratie: Maart 2004
  • Laatst online: 30-01 17:16
djluc schreef op 07 oktober 2004 @ 17:48:
Ok, je mening is duidelijk. Wat voor je sowieso interessant is om door te nemen: de source van Squirrelmail. Deze werkt ook zonder de module.
Ik heb daar al een aantal malen in zitten kijken, maar echt gemakkelijk is dat niet te ontcijferen. Functies worden over en weer aangeroepen. Maar ik blijf proberen om iets te vinden waar ik wat aan heb.

[ Voor 5% gewijzigd door MarkvE op 07-10-2004 17:53 ]

Vormkracht10


Acties:
  • 0 Henk 'm!

  • stekkel
  • Registratie: Augustus 2001
  • Laatst online: 17-09 08:05
Met name de file imap_general.php is van belang, zie:
http://cvs.sourceforge.ne...php?rev=1.196&view=markup

In squirrelmail kan je met sqimap_run_command een imap call doen. De return waarde bevat de imap response in een array (elke untagged response is een array element). De response en message parameters bevatten de imap response (OK|NO|BAD|BYE ... ) met bijbehorend bericht.

Ik weet dat de imap backend code een beetje een chaos is en niet eens unsollicited responses aankan (ben de hele meuk aan het herschrijven) maar voor de rest werkt die imap backend code best aardig gezien het aantal mensen dat squirrelmail gebruikt.

Over RFC3501. Vind het niet echt beknopt en het hele imap protocol staat er toch echt beschreven. Het is af en toe wel wat lastig te interpreteren maar met als referentie de imap mailinglist kom je een heel eind.

Acties:
  • 0 Henk 'm!

  • KnoppenSpook
  • Registratie: Augustus 2000
  • Laatst online: 04-09-2023
IlohaMail werkt ook zonder module, met een duidelijk API omschrijving.

http://www.ilohamail.org/

/me weet geen leuke quote voor in zijn signature


Acties:
  • 0 Henk 'm!

  • MarkvE
  • Registratie: Maart 2004
  • Laatst online: 30-01 17:16
Hoe kun je eigenlijk via deze weg connecten met IMAP via SSL? Als ik namelijk via de IMAP module van PHP een connectie met de IMAP server aanleg dan moet ik de SSL parameters (/ssl/novalidate-cert, red.) gebruiken...

Vormkracht10


Acties:
  • 0 Henk 'm!

  • MarkvE
  • Registratie: Maart 2004
  • Laatst online: 30-01 17:16
Maar wat ik vooralsnog het minst begrijp, is dat wanneer ik de RFC lees dat er staat dat je bij een SELECT INBOX dit terug krijgt:
Example: C: A142 SELECT INBOX
S: * 172 EXISTS
S: * 1 RECENT
S: * OK [UNSEEN 12] Message 12 is first unseen
S: * OK [UIDVALIDITY 3857529045] UIDs valid
S: * OK [UIDNEXT 4392] Predicted next UID
S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
S: * OK [PERMANENTFLAGS (\Deleted \Seen \*)] Limited
S: A142 OK [READ-WRITE] SELECT completed
Terwijl ik alleen dit terug krijg:
* FLAGS (\Draft \Answered \Flagged \Deleted \Seen \Recent)
En wanneer ik bijvoorbeeld iets als dit doe:
S2 STATUS "INBOX" (MESSAGES)
S3 STATUS "INBOX.Trash" (MESSAGES)
S4 STATUS "INBOX.Sjah" (MESSAGES)
Dan krijg ik slechts dit terug:
* STATUS "INBOX" (MESSAGES 0)
S2 OK STATUS Completed.
* STATUS "INBOX.Trash" (MESSAGES 1)
Terwijl ik toch echt de respons opvraag:

PHP:
1
echo fgets ( $this -> connection, 4096 );


Hoe kan dat toch?

[ Voor 29% gewijzigd door MarkvE op 08-10-2004 21:11 ]

Vormkracht10


Acties:
  • 0 Henk 'm!

  • stekkel
  • Registratie: Augustus 2001
  • Laatst online: 17-09 08:05
logisch, fgets pakt iedere keer 1 regel. Je moet net zolang doorgaan met fgets calls totdat je een tagged response terug krijgt.

Dus als je doet:
A006 SELECT INBOX
dan doe je fgets in een while lus en wanneer je als response
A006 ..... (je tag) ontvangt dan break je en check je wat de server response is (OK|BAD|NO|BYE)

Acties:
  • 0 Henk 'm!

  • MarkvE
  • Registratie: Maart 2004
  • Laatst online: 30-01 17:16
stekkel schreef op 08 oktober 2004 @ 21:28:
logisch, fgets pakt iedere keer 1 regel. Je moet net zolang doorgaan met fgets calls totdat je een tagged response terug krijgt.

Dus als je doet:
A006 SELECT INBOX
dan doe je fgets in een while lus en wanneer je als response
A006 ..... (je tag) ontvangt dan break je en check je wat de server response is (OK|BAD|NO|BYE)
Als ik dat doe, dan kom ik (kennelijk) uit in een oneindige loop, aangezien de pagina dan maar blijft laden...

PHP:
1
2
3
4
5
6
7
8
9
10
// $this -> prefix = de tag

$buffer = '';
                
while ( !strPos ( $buffer, $this -> prefix ) )
{
    $buffer.= fgets ( $this -> connection, 4096 );
};
                
echo $buffer;

[ Voor 4% gewijzigd door MarkvE op 08-10-2004 23:00 ]

Vormkracht10


Acties:
  • 0 Henk 'm!

  • MarkvE
  • Registratie: Maart 2004
  • Laatst online: 30-01 17:16
Ik ben er eindelijk uit :)

Op de één of andere manier wilde het maar niet lukken op verschillende manieren, maar nu is het uiteindelijk gelukt met de volgende oplossing:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$output = ''
$boolean = true;
                
while ( $boolean )
{
    $buffer = fgets ( $this -> connection, 512 );
    $output.= $buffer;
                    
    if ( strPos ( $buffer, 'S' . $this -> prefix ) !== false )
    {
        $boolean = false;
    };
};
                
echo $output;


Deze loop blijft doorgaan totdat er geen respons meer is van de server (dus: wanneer de respons niet begint met de opgegeven tag).

Mijn fout was volgens mij dat ik telkens dacht in: als $buffer leeg is (er is geen respons) dan moet de loop worden gestopt, maar wanneer $buffer leeg is, loopt die loop toch nog een keer door en daardoor blijft je script hangen omdat hij niks terug krijgt van fgets().

[ Voor 38% gewijzigd door MarkvE op 09-10-2004 11:45 ]

Vormkracht10

Pagina: 1