Windows.  Virus.  Anteckningsböcker.  Internet.  kontor.  Verktyg.  Förare


E-post- det här är det viktigaste verktyget för att utbyta information, och om du använder det i arbetet måste du ha stött på en situation: ett brev kommer med posten, som innehåller de uppgifter som behövs för bearbetning av ett skript. Vi kommer att prata om Yandex-post - i den här artikeln kommer jag att dela med dig, kära läsare, erfarenheten av hur man får brev ur brevlådan, vi kommer också att analysera alternativet när brevet har en bifogad fil - hur man upptäcker det och så småningom ladda ner den för ytterligare manipulationer på den.

Jag själv stod inför denna uppgift för länge sedan, och sedan, med liten erfarenhet av Yandex-e-postprogram, tillbringade jag mycket tid och nerver för att uppnå det önskade resultatet. Mitt första misstag var att jag, likt många webbutvecklare, började intensivt söka efter liknande exempel på webben, men använde inte själva Yandex-hjälpen (hjälpen). Ja, det finns användbar information där, även om den är väldigt liten, men den är tillräckligt viktig för att skriva den här typen av manus (mer om det nedan). Vid den tiden var det nödvändigt att skriva ett manus, vars kärna var: ett brev med en prislista över varor i xls-format skickades till Yandex-post från kunden en gång om dagen, det måste bearbetas (tolkas och jämföras med data från onlinebutikens databas och, beroende på resultatet, något sedan uppdatera någonstans, inaktivera eller aktivera).

Och det första vi kommer att göra innan vi skriver manuset är att beskriva vår handlingsplan, som kommer att bestå av nio punkter:

  1. Konfigurera e-post för att få åtkomst via e-postprotokoll;
  2. Låt oss beskriva själva strukturen PHP-applikationer och besluta om filkodningen;
  3. Låt oss bekanta oss med IMAP-e-postprotokollet och dess möjligheter;
  4. Anslut till Yandex-e-post via kontoinloggning och lösenord och spåra fel i detta skede;
  5. Låt oss behandla brevets rubrik;
  6. Vi tar emot och behandlar brevets brödtext;
  7. Hämta och spara bifogade filer;
  8. Vi visualiserar det utförda arbetet;
  9. Låt oss dra slutsatser.

Ämnet är ganska omfattande, men jag ska försöka förklara allt så kompakt och tydligt som möjligt. Låt oss kanske börja.

E-postinställningar

Gå till din e-post och gå till inställningarna, som visas i skärmdumpen nedan:



Nu kom vi in ​​på inställningarna för e-post via IMAP- och POP3-protokollen:


Här kommer många att se en bild som på bilden ovan, men jag har stött på, och mer än en gång, när åtkomsten är inaktiverad. Därför, om dina inställningar är annorlunda, markera rutorna som på skärmdumpen, det viktigaste för oss är att tillåta åtkomst via IMAP-protokollet.

Applikationsstruktur och dess kodning

I det här exemplet kommer vi inte att komma med en komplex applikationsstruktur, eftersom den inte behövs, utan vi lägger bara till det som är nödvändigt (jag arbetar i Sublime Text-redigeraren):


  • tmp - mapp där vi laddar upp bilagor från brevet, om några;
  • .htaccess - inställning på serversidan om du har apache-server;
  • functions.php - vi kommer att lägga till våra funktioner här;
  • main.css - stilfil;
  • index.php - applikationsingångspunkt;

Vi kommer att använda UTF-8-kodning och fyller därför omedelbart .htaccess-filen med följande rader:

AddDefaultCharset utf-8 AddCharset utf-8 * CharsetSourceEnc utf-8 CharsetDefault utf-8

IMAP-protokoll

För att återgå till den första punkten är det tydligt att du också kan arbeta med Yandex-post genom POP3-protokollet. Så varför just IMAP? Av de två är IMAP det nyare och alternativet till POP3, så det har en rad fördelar (som finns på wikipedia), men i vårt fall påverkades valet bara av att det är nyare. Personligen ser jag inte så stor skillnad vad man ska använda under specifik uppgift får ett brev. Om du av någon anledning behöver använda POP3-protokollet, kommer alla funktioner som gäller för IMAP att fungera för honom.

Ansluter till Yandex-e-post med IMAP-protokollet

För att kunna ansluta till e-posten behöver vi känna till tre parametrar: e-postinloggning, dess lösenord och adress Mejl server. Om det inte finns några problem med två parametrar, kan den andra hittas i Yandex. Jag skrev om detta (problemet som jag hade) ovan och skrev många exempel på nätverket där den tredje parametern inte är korrekt specificerad och tänk dig att fel uppstår redan vid anslutningsstadiet - detta är åtminstone obehagligt. Jag kommer inte att slå runt busken och omedelbart ge en direktlänk till Yandex-sidan - miljö e-postprogram . Här är vad vi behöver för att ansluta:


Nu kan du gå direkt till själva koden:

Header("Content-Type: text/html; charset=utf-8"); error_reporting(0); require_once("functions.php"); $mail_login = "yandex_mail"; $mail_password = "mail_password"; $mail_imap = "(imap.yandex.ru:993/imap/ssl)"; // Lista över filtyper att överväga $mail_filetypes = array("MSWORD"); $connection = imap_open($mail_imap, $mail_login, $mail_password); if(!$connection)( echo("E-postanslutning misslyckades - ".$mail_login); avsluta; )else( $msg_num = imap_num_msg($connection); $mails_data = array(); for($i = 1; $ i<= $msg_num; $i++){ /* Работать с каждым письмом из IMAP-потока будем тут */ } } imap_close($connection);

Först och främst anger vi dessutom UTF-8-kodningen med hjälp av rubriken och stänger av visningen av fel. Vi ansluter functions.php-filen och specificerar inställningarna som diskuterades ovan. I arrayen $mail_filetypes anger vi de filformat som vi behöver. Det beslutades att göra det för att sålla bort onödigt skräp och ta emot specifika filer. Anslutningen till posten görs med hjälp av funktionen imap_open() som returnerar en IMAP-ström vid framgång och falsk vid misslyckande (men om du aktiverar felvisning är detta inte fallet). Vi avslutar arbetet med strömmar med funktionen imap_close () och skickar den till en anslutningsindikator. Mellan dessa två funktioner finns en vanlig villkorlig operator.

Om anslutningen lyckas, med hjälp av imap_num_msg(), tar vi reda på antalet bokstäver i posten och lägger till en array där vi lägger all data vi behöver från strömmen. Detta följs av en cykel där varje bokstav kommer att behandlas med sitt nummer (numreringen börjar från 1) separat.

Bearbetning av e-posthuvud

För att få e-posthuvudet måste du använda funktionen imap_header(), vars andra parameter är e-postnumret:

// E-posthuvud $msg_header = imap_header($anslutning, $i);

I det här skedet kommer vi att ta emot ett objekt från vilket vi hämtar den data vi behöver och sparar den i arrayen $mails_data. Här är ett exempel på en av bokstäverna:

Den här skärmdumpen visar att all data är duplicerad, men detta spelar ingen speciell roll, vi drar det som är bekvämare. Mycket viktigare är kodningen av ämnesraden. Det kan vara vad som helst och det här ögonblicket måste kontrolleras. Samma situation är med brevets brödtext och med bifogade filer.

$mails_data[$i]["time"] = tid($msg_header->MailDate); $mails_data[$i]["date"] = $msg_header->MailDate; foreach($msg_header->to as $data)( $mails_data[$i]["to"] = $data->mailbox."@".$data->host; ) foreach($msg_header->from as $ data)( $mails_data[$i]["from"] = $data->mailbox."@".$data->host; )

Vi lagrar i vårt array: en tidsstämpel, datumet för mottagandet av brevet, e-postmeddelandet till mottagaren och avsändaren och fortsätter att ta emot brevets ämne. För att göra detta måste vi först lägga till tre funktioner i filen functions.php:

Funktion check_utf8($charset)( if(strtolower($charset) != "utf-8")( return false; ) return true; ) funktion convert_to_utf8($in_charset, $str)( return iconv(strtolower($in_charset), "utf-8", $str); ) funktion get_imap_title($str)( $mime = imap_mime_header_decode($str); $title = ""; foreach($mime som $key => $m)( if(!check_utf8 ($m->charset))( $title .= convert_to_utf8($m->charset, $m->text); )else( $title .= $m->text; ) ) return $title; )

Namnen är självförklarande och jag tycker att det är värt att förklara bara den sista funktionen. Den tar en kodad sträng och avkodar den med imap_mime_header_decode() , som returnerar en array av objekt, som vart och ett har två egenskaper charset (kodning) och text (tematext). Då är allt enkelt: i en slinga, genom att kontrollera kodningen, konverterar vi den till UTF-8 och limar ämnet i en enda rubrik och returnerar den.

Låt oss nu gå tillbaka till filen index.php och dra ut den sista parametern:

$mails_data[$i]["title"] = get_imap_title($msg_header->subject);

Detta avslutar behandlingen av brevhuvudet.

Arbeta med brevets brödtext

Vi fortsätter att gradvis forma vår array med den bearbetade e-postdatan, och nu måste vi använda två funktioner för att få kroppen:

// Message body $msg_structure = imap_fetchstructure($connection, $i); $msg_body = imap_fetchbody($connection, $i, 1);

Den första variabeln $msg_structure innehåller bokstavens struktur - det här är ett objekt där du kan hitta massan användbar information, ett exempel på en del av detta objekt visas nedan:

Vad är viktigt för att lösa vårt problem:

  • typ - den primära typen av brevets kropp, beroende på vad som kommer till oss i posten, kan den variera från 0 till 7 (varje siffra anger sin egen typ av innehåll som finns i brevets brödtext);
  • kodning - kroppsöverföringskodning, varierar från 0 till 5 (0 - 7BIT, 1 - 8BIT, 2 - BINÄR, 3 - BASE64, 4 - UTSKRIFTBAR CITERAT, 5 - ANNAT);
  • delar är en samling bokstavsdelar som motsvarar objektets struktur en nivå upp.

Låt oss ta en närmare titt på delarnas egendom. Det första att säga är att i nollcellen i denna array finns information som exakt motsvarar brevets text, och från den första - till bifogade filer. Dessutom anges i varje objekttyp och i parametrar är kodningen explicit och implicit.

Bokstavens struktur kan kapslas hur mycket du vill, åtminstone hade jag fall när den nådde fyra eller fem nivåer, så för att irritera den, som de säger, måste vi skriva en rekursiv funktion i framtiden.

Den andra imap_fetchbody()-funktionen hämtar en specifik del av e-postmeddelandet, oftast i kodad form.

Låt oss nu lägga till en variabel där vi kommer att spara den bearbetade versionen av brevets kropp:

$kropp = "";

Låt oss gå tillbaka till functions.php-filen och skriva en rekursiv funktion:

Funktion recursive_search($structure)( $encoding = ""; if($structure->subtype == "HTML" || $structure->typ == 0)( if($structure->parameters->attribute == " charset")( $charset = $struktur->parametrar->värde; ) return array("encoding" => $structure->encoding, "charset" => strtolower($charset), "subtype" => $struktur- >undertyp); )else( if(isset($struktur->delar))( returnerar rekursiv_sökning($struktur->delar); )else( if($struktur->parametrar->attribut == "teckenuppsättning")( $ charset = $struktur->parametrar->värde; ) return array("encoding" => $structure->encoding, "charset" => strtolower($charset), "subtype" => $structure->subtype); ) ))

Funktionen recursive_search() tar en parameter - bokstavens struktur, där den sekventiellt kontrollerar egenskaperna och får tre parametrar: kodning, teckenuppsättning, undertyp. Utgångspunkten från rekursionen är frånvaron av partsegenskapen med en nollcell. Det finns inget mer att förklara här, jag tycker att det framgår av koden vad som händer och hur.

Låt oss lägga till ytterligare en funktion för att konvertera bokstavens kropp, som vi kommer att behöva i framtiden:

Funktion structure_encoding($encoding, $msg_body)( switch((int) $encoding)( fall 4: $body = imap_qprint($msg_body); break; fall 3: $body = imap_base64($msg_body); break; fall 2: $body = imap_binary($msg_body); break; fall 1: $body = imap_8bit($msg_body); break; fall 0: $body = $msg_body; break; default: $body = ""; break; ) returnera $body ;)

$rekursiv_data = rekursiv_sökning($msg_struktur); if($recursive_data["encoding"] == 0 || $recursive_data["encoding"] == 1)( $body = $msg_body; ) if($recursive_data["encoding"] == 4)( $body = structure_encoding($recursive_data["encoding"], $msg_body); ) if($recursive_data["encoding"] == 3)( $body = structure_encoding($recursive_data["encoding"], $msg_body); ) if($ recursive_data["encoding"] == 2)( $body = structure_encoding($recursive_data["encoding"], $msg_body); ) if(!check_utf8($recursive_data["charset"]))( $body = convert_to_utf8($ recursive_data["charset"], $msg_body); )

Efter att vi har fått data från rekursionen kontrollerar vi gradvis överföringskodningen och, beroende på detta, anropar vi struktur_encoding ()-funktionen med lämpliga parametrar. I den sista Villkorligt uttalande vi tar hänsyn till att vi arbetar i UTF-8 och om vi efter alla manipulationer får något annat än kodningen, kommer vi att koda om det.

Det återstår att dra en linje:

$mails_data[$i]["body"] = base64_encode($body);

Brödtexten kan innehålla både vanlig text och HTML-uppmärkning med sina egna stilar. Vi kodar i BASE64 så att vår layout inte blir fel under renderingen.

Bifogade filer

Här närmar vi oss gradvis slutet av att skriva vår ansökan:

// Kapslade filer if(isset($msg_structure->parts))( for($j = 1, $f = 2; $j< count($msg_structure->delar); $j++, $f++)( if(in_array($msg_structure->parts[$j]->subtype, $mail_filetypes))( $mails_data[$i]["attachs"][$j]["type"] = $msg_structure->parts[$j]->subtype; $mails_data[$i]["attachs"][$j]["size"] = $msg_structure->parts[$j]->bytes; $mails_data[ $i]["attachs"][$j]["name"] = get_imap_title($msg_structure->parts[$j]->parameters->value); $mails_data[$i]["attachs"][$ j]["file"] = structure_encoding($msg_structure->parts[$j]->encoding, imap_fetchbody($connection, $i, $f)); file_put_contents("tmp/".iconv("utf-8" , "cp1251", $mails_data[$i]["attachs"][$j]["name"]), $mails_data[$i]["attachs"][$j]["file"]); ) ))

Den bit som ansvarar för att bearbeta den bifogade filen är mycket mindre, och nu - varför exakt. Principen för att arbeta med en fil liknar att arbeta med en bokstavs brödtext, bara detta steg börjar med dess närvaro i arrayen av delarnas egenskap. Glöm inte att filtrera bort de onödiga, med hänvisning till listan över typer. Med den enkla funktionen file_put_contents() sparar vi vår fil på vår server i tmp-mappen.

Jag vill se resultatet!

Under arbetets gång har vi skapat en array med $mails_data-data, och för visualisering kommer vi redan att arbeta direkt med den. I den här artikeln använde jag ett testbrev som jag hade på posten, låt oss se vad vi fick till slut:


Detta är vilken typ av array du borde få, tyvärr, jag var tvungen att dölja innehållet i filen av personliga skäl. Låt oss nu gå vidare till vår HTML-uppmärkning:

Yandex Mail |<?php echo($mail_login);?>

Yandex Mail (Inkorg) |

Antal bokstäver:

inga bokstäver
$mail):?>
Tidsstämpel:
Datum för:
Till vem:
Från:
Ämne:
Bokstav i base64:
Bifogade filer:
$attach):?>
Typ:
Storlek (i byte):
Namn:
Kropp:

Jag kommer inte att lägga till stilar här, eftersom de inte spelar någon speciell roll, i slutändan:


Och på servern i tmp-mappen kommer du att ha en fil.

Slutsats

Efter att ha slutfört alla steg från artikeln kommer du att uppnå rätt resultat, men allt är inte så enkelt som det kan verka - det finns fallgropar som måste beaktas. När du skriver ett manus för en specifik uppgift är det nödvändigt att följa kodningen i alla skeden, brev kan komma från olika e-postmeddelanden, som var och en kan ha sina egna nyanser. Det kommer också att vara viktigt att ta hänsyn till att Yandex-post och deras dokumentation uppdateras med jämna mellanrum, så olika underpunkter för att arbeta med e-postprogram kan visas. Det var allt för mig, jag hoppas att du tycker att den här artikeln är användbar när du arbetar med en version på lägre nivå av Yandex-e-post.

Det går inte att ta emot e-post med bilaga
om post skickas med en fil - vilken som helst - så försvinner brevets text

snälla hjälp mig

Det är klart ... om du överför e-post från Yandex till Yandex, så fungerar allt ...
har liksom kommit på det
men det är därför det här skriptet inte accepterar andra filer förutom Word, det är inte klart ... det finns en MSWORD-rad bredvid den, separerad med kommatecken, lägg både PDF och JPG och PNG - bara Word läser och sparar normalt ... . något som det här

En möjlig användning av imap-funktionerna är att skapa en e-postdemon som kommer att hantera prenumeration och avregistrering av användare från din e-postlista. För att utföra denna uppgift används vanligtvis två metoder i e-postlistor. Den första förutsätter att användaren måste gå till en viss sida och bekräfta sina handlingar, den andra kräver att man skickar ett e-postmeddelande. Den andra kräver också att skripthanteraren körs regelbundet av cron daemon-om. På grund av detta är den inte lika populär som den första metoden.

Men som du kan se använder de mest seriösa utskick den andra metoden. Så om du har möjlighet att använda cron, använd det.

Det är faktiskt inte svårt att förstå funktionerna. Vissa svårigheter kan uppstå med att analysera rubrikerna på bokstäver som skriptet kommer att bearbeta.

Algoritmen för själva skriptet är lätt att komma på. Demonen upprättar en anslutning till e-postservern och söker efter meddelanden på den. Om det inte finns några bokstäver stoppas skriptet. Om det finns bokstäver tolkas rubrikerna på den första bokstaven. Från och ämnesfälten slås upp. Om ämnesfältet innehåller ett av de två giltiga rubrikalternativen (prenumerera eller avsluta prenumeration), blir posten som motsvarar värdet för från-fältet antingen aktiv (bekräftad) eller tas bort från tabellen. I båda fallen skickas ett motsvarande meddelande om skriptets handlingar till den adress som anges i från-fältet. E-postmeddelandet markeras sedan för radering. Om ämnet inte innehåller giltiga ämnen skickas ett felmeddelande och mejlet markeras även för radering. Skriptet går sedan vidare till nästa e-postmeddelande. Efter att ha analyserat alla bokstäverna rensar han rutan.

Funktionen imap_open används för att öppna brevlådan. Eftersom PHP stöder flera protokoll är det nödvändigt att uttryckligen ange vilket protokoll som används för att arbeta med rutan. I vårt fall är detta pop3 på port 110 (standard). Vi tilldelar resultatet av skriptkörningen till variabeln $my_box.

$my_box = imap_open("(you.pop.host/pop3:110)", "login", "lösenord");

Senare kommer du att se att denna variabel kommer att användas i nästan alla imap-funktioner. Kolla sedan efter brev i brevlådan. Kontrollen utförs av funktionen imap_num_msg.

$n = imap_num_msg($my_box);

Som ett resultat kommer variabeln $n att innehålla antalet bokstäver i brevlådan. Detta nummer kan antingen vara större än noll eller lika med det (om rutan är tom). Om det finns bokstäver, tolkar vi i while-slingan bokstäverna och ökar sekventiellt numret på bokstaven med en. Observera att den första bokstaven i rutan kommer att ha siffran 0, liksom det första elementet i arrayen. För att öka numret på bokstaven tilldelar vi variabeln $m värdet 0, och sedan, under slingans villkor, ökar vi det med en $m++.

Två funktioner räcker för att analysera de rubriker vi är intresserade av: imap_header och imap_fetch_overview . För att utföra var och en av dem, förutom rutan, måste du ange numret på bokstaven. I vårt fall, inuti slingan, kommer den att vara lika med variabeln $m.

imap_header returnerar ett objekt som innehåller uttömmande information om meddelandehuvudet som ett resultat av exekvering. Detta objekt innehåller bland annat en array som innehåller fyra värden. Dessa är personal, adl, mailbox och host. Av dessa är vi bara intresserade av brevlåda och värd. Genom att ersätta dem får vi adressen från vilken brevet skickades.

$h = imap_header($my_box, $m); $h = $h->från; foreach ($h som $k => $v) ( $mailbox = $v->mailbox; $host = $v->host; $personal = $v->personal; $email = $mailbox . "@" . $host;

imap_fetch_overview - gör det möjligt för oss att ta reda på ämnet för brevet. För samma ändamål kan imap_header också användas, men av flera anledningar kanske det ibland inte fungerar. Från arrayen som denna funktion returnerar behöver vi bara ämnesfältet

$s = imap_fetch_overview($my_box, $m); foreach ($s som $k => $v) $subj = $v->subject;

Våra nästa steg är att extrahera e-postmeddelandet från databasen, och om det finns där, markera hela raden med denna post som eller ta bort den. Antag att efter att ha fyllt i e-postformuläret på webbplatsen tilldelas prenumeranten statusen 0, och efter att ha bekräftat prenumerationen ändras den till 1.

If ($subj == "prenumerera") ( mysql_query("update prescribe set stat=1 där email=$my_email"); $del = imap_delete($my_box, $m); mail($email, $add_sbj, $add_text , $headers); ) else if ($subj == "unsubscribe") ( mysql_query("radera från prenumeration där e-post = $my_email"); $del = imap_delete($my_box, $m); mail($email, $ del_sbj, $del_text, $headers); ) else ( $del = imap_delete($my_box, $m); mail($email, $err_sbj, $err_text, $headers); ) efter alla åtgärder rensar skriptet rutan. $clear = imap_expunge($my_box);

Detta enklaste program är bara en demonstration av det faktum att PHP kan skriva inte bara dynamiskt föränderliga webbplatser, utan även tjänster som inte alls är synliga för användaren.

Lista över hela programmet förutom databasanslutningsparametrarna:

inkludera "config.php"; // databasanslutning $my_box = imap_open("(you.pop.host/pop3:110)", "login", "lösenord"); $n = imap_num_msg($my_box); $m = 0; $add_text = "Tack för att du bekräftade din prenumeration"; $add_sbj = "du lade till!"; $del_text = "Du har tagits bort från e-postlistan. "; $del_sbj = "ta bort från listan"; $err_text = "Tyvärr, men den här brevlådan används endast för administration av e-postlistor"; $err_sbj = "fel"; $headers = "från: prenumerera robot x-mailer: php4 innehållstyp: text/plain; charset=windows-1251 "; if($n != 0) ( while($m++< $n) { $h = imap_header($my_box, $m); $s = imap_fetch_overview($my_box, $m); $h = $h->från; foreach ($h som $k =>$v) ( $mailbox = $v->mailbox; $host = $v->host; $personal = $v->personal; $email = $mailbox . "@" . $host; $my_email = mysql_escape_string($email); ) foreach ($s som $k => $v) $subj = $v->subject; if ($subj == "prenumerera") ( mysql_query("uppdatera tabelluppsättning stat=1 där e-post=$min_e-post"); //print mysql_error(); $del = imap_delete($my_box, $m); mail($ email, $add_sbj, $add_text, $headers); ) else if ($subj == "avsluta prenumeration") ( mysql_query("radera från tabell där e-post = $my_email"); $del = imap_delete($my_box, $m) ; mail($email, $del_sbj, $del_text, $headers); ) else ( $del = imap_delete($open_box, $m); mail($email, $err_sbj, $err_text, $headers); ) ) $clear = imap_expunge($my_box); )

Listan saknar vissa detaljer, såsom en eventuell konvertering från vinst till koi, kontroll av avsändarens brevlåda, etc. Det är redan funktionella överdrifter som alla kan lägga till efter behov.

En möjlig användning av imap-funktionerna är att skapa en e-postdemon som kommer att hantera prenumeration och avregistrering av användare från din e-postlista. För att utföra denna uppgift används vanligtvis två metoder i e-postlistor. Den första förutsätter att användaren måste gå till en viss sida och bekräfta sina handlingar, den andra kräver att man skickar ett e-postmeddelande. Den andra kräver också att skripthanteraren körs regelbundet av cron daemon?om. På grund av detta är den inte lika populär som den första metoden.

Men som du kan se använder de mest seriösa utskick den andra metoden. Därför, om du har möjlighet att använda crond, använd den.

Det är faktiskt inte så svårt att förstå funktionerna. En person som tidigare arbetat för PHP kommer lätt att förstå hur man arbetar med dem. Vissa svårigheter kan uppstå med att analysera rubrikerna på bokstäver som skriptet kommer att bearbeta.

Algoritmen för själva skriptet är lätt att komma på. Demonen upprättar en anslutning till e-postservern och söker efter meddelanden på den. Om det inte finns några bokstäver stoppas skriptet.
Om det finns bokstäver tolkas rubrikerna på den första bokstaven. Från och ämnesfälten slås upp. Om ämnesfältet innehåller ett av de två giltiga rubrikalternativen (prenumerera eller avsluta prenumeration), blir posten som motsvarar värdet för från-fältet antingen aktiv (bekräftad) eller tas bort från tabellen. I båda fallen skickas ett motsvarande meddelande om skriptets handlingar till den adress som anges i från-fältet. E-postmeddelandet markeras sedan för radering. Om ämnet inte innehåller giltiga ämnen skickas ett felmeddelande och mejlet markeras även för radering. Skriptet går sedan vidare till nästa e-postmeddelande.
Efter att ha analyserat alla bokstäverna rensar han rutan.

Jag kommer inte att tråka ut läsaren med flödesscheman, så låt oss gå direkt till saken. Funktionen imap_open används för att öppna brevlådan. Eftersom PHP stöder flera protokoll måste du uttryckligen ange vilket protokoll som används för att fungera med rutan. I vårt fall är detta POP3 på port 110 (standard). Vi tilldelar resultatet av skriptkörningen till variabeln $my_box.


Senare kommer du att se att denna variabel kommer att användas i nästan alla imap-funktioner. Kolla sedan efter brev i brevlådan. Kontrollen utförs av funktionen imap_num_msg.

$n = imap_num_msg ($my_box );

Som ett resultat kommer variabeln $n att innehålla antalet bokstäver i brevlådan. Detta nummer kan antingen vara större än noll eller lika med det (om rutan är tom).
Om det finns bokstäver, tolkar vi i while-slingan bokstäverna och ökar sekventiellt numret på bokstaven med en. Observera att den första bokstaven i rutan kommer att ha siffran 0, liksom det första elementet i arrayen.
För att öka numret på bokstaven tilldelar vi variabeln $m värdet 0, och sedan, under slingans villkor, ökar vi det med en $m++.

För att analysera de rubriker vi är intresserade av räcker det med två funktioner: imap_header och imap_fetch_overview. För att utföra var och en av dem, förutom rutan, måste du ange numret på bokstaven. I vårt fall, inuti slingan, kommer den att vara lika med variabeln $m.

Imap_header returnerar som ett resultat av exekvering ett objekt som innehåller omfattande information om meddelandehuvudet. Detta objekt innehåller bland annat en array som innehåller fyra värden. Dessa är personal, adl, mailbox och host. Av dessa är vi bara intresserade av brevlåda och värd. Genom att ersätta dem får vi adressen från vilken brevet skickades.


$h = $h -> från ;
a
foreach ($h som $k => $v ) (
$mailbox = $v -> brevlåda ;
$host = $v -> värd ;
$personlig = $v -> personlig ;
$email = $mailbox . ? @ ¬ . $ värd ;

imap_fetch_overview - kommer att informera oss om ämnet för e-postmeddelandet. För samma ändamål kan imap_header också användas, men av flera anledningar kanske det ibland inte fungerar. Från arrayen som denna funktion returnerar behöver vi bara ämnesfältet


foreach ($s som $k => $v ) (
$subj = $v -> ämne ;
}

Våra nästa steg är att extrahera e-postmeddelandet från databasen, och om det finns där, markera hela raden med denna post som "verifierad" eller ta bort den. Antag att efter att ha fyllt i e-postformuläret på webbplatsen tilldelas prenumeranten statusen 0, och efter att ha bekräftat prenumerationen ändras den till 1.

if ($subj == "PRENUMERERA" ) (
mysql_query( "UPPDATERA prenumerera SET stat=1 WHERE email=$my_email");

}
mysql_query( "DELETE FROM prenumerera WHERE email = $my_email");
$del = imap_delete ($my_box , $m );
}
annan(
$del = imap_delete ($my_box , $m );
}

som nämnts ovan, efter att ha utfört alla åtgärder, rensar skriptet rutan.


Detta enklaste program är bara en demonstration av det faktum att du kan skriva i PHP inte bara dynamiskt föränderliga webbplatser, utan även tjänster som inte alls är synliga för användaren. Naturligtvis, när det gäller skalskript, är PHP inte tillämpligt, till skillnad från sin konkurrent Perl, men ändå ...

Lista över hela programmet förutom databasanslutningsparametrarna (db.php):

inkludera "db.php" ;
$my_box = imap_open ("(you.pop.host/pop3:110)", "login", "lösenord" );
$n = imap_num_msg ($my_box );
$m = 0 ;
$add_text = "

Tack för att du bekräftar din prenumeration " ;
$add_sbj = "Du lade till!" ;
$del_text = "

Tyvärr, men den här brevlådan används.
endast för distributionsadministration" ;
$err_sbj = "Fel" ;
$headers = Från: Prenumerera Robot

Xmailer: PHP4

Innehållstyp: text/vanlig; charset=UTF-8
" ;
om($n != 0 ) (
while($m++< $n ) {
$h = imap_header ($my_box , $m );
$s = imap_fetch_overview ($my_box , $m );
$h = $h -> från ;
foreach ($h som $k => $v ) (
$mailbox = $v -> brevlåda ;
$host = $v -> värd ;
$personlig = $v -> personlig ;
$email = $mailbox . "@" . $ värd ;
$my_email = mysql_escape_string($email );
}
foreach ($s som $k => $v ) (
$subj = $v -> ämne ;
}
if ($subj == "PRENUMERERA" ) (
mysql_query( "UPPDATERA tabell SET stat=1 WHERE email=$my_email");
//skriv ut mysql_error();
$del = imap_delete ($my_box , $m );
mail ($email , $add_sbj , $add_text , $headers );
}
elseif ($subj == "AVSLUTA PRENUMERERA" ) (
mysql_query( "RADERA FRÅN tabell WHERE email = $my_email");
$del = imap_delete ($my_box , $m );
mail ($email , $del_sbj , $del_text , $headers );
}
annan(
$del = imap_delete ($open_box , $m );
mail ($email , $err_sbj , $err_text , $headers );
}
}
$clear = imap_expunge($my_box);
}
?>

Häromdagen fick jag en uppgift att skriva en liten PHP-modul som skulle tillåta mig att arbeta med inkommande post. Googlade lite såg jag att ett av protokollen passar mig för denna uppgift POP3 Och IMAP.
Men valet var självklart att jag skulle använda IMAP, då det är mer funktionellt och modernare än POP3-protokollet.

Nu var jag tvungen att snabbt ta reda på hur man arbetar med IMAP-protokollen, hur man tar emot brev från Yandex/Googles e-postserver.

För mer bekvämt arbete valde jag biblioteket PhpImap, eftersom det snabbt och enkelt kan implementera alla uppgifter jag behöver.

Ansluter till en e-postserver.

Nu när vi har bestämt oss för val av protokoll och val av bibliotek ska vi försöka koppla upp oss mot mailservern.

För att PHP ska fungera fullt ut med IMAP-protokollet måste du ansluta tillägget php_imap.dll/imap.so i filen php.ini.

Till att börja med, låt oss försöka ansluta till Yandex-e-post, eftersom jag hade minst problem med det.

//Inkludera bibliotek include("/phpImap/Mailbox.php"); include("/phpImap/IncomingMail.php"); //För enkelhetens skull, låt oss skapa konstanter för att ansluta till e-postservern. define("MAIL_IMAP_SERVER", "imap.yandex.ru"); define("MAIL_IMAP_SERVER_PORT", 993); define("MAIL_IMAP_LOGIN", " "); define("MAIL_IMAP_PASS", "example_pass"); define("MAIL_IMAP_PATH", "(".MAIL_IMAP_SERVER.":".MAIL_IMAP_SERVER_PORT."/imap/ssl)INBOX"); $mailbox = new PhpImap\Mailbox(MAIL_IMAP_PATH, MAIL_IMAP_LOGIN, MAIL_IMAP_PASS, __DIR__); try ( $mailbox->getImapStream(); ) catch (Undantag $e) (die($e->getMessage()); )

Hur ser vi på klasskonstruktören Brevlåda tar följande argument:

  • MAIL_IMAP_PATH- Innehåller serveradress (MAIL_IMAP_SERVER), anslutningsport (MAIL_IMAP_SERVER_PORT), anslutningstyp (imap) och indikerar att anslutningen kommer att krypteras (ssl). Efter de lockiga parenteserna anger vi mappen som vi kommer att ansluta till, i det här fallet, till inkommande meddelanden (INBOX).
  • MAIL_IMAP_LOGIN– Brevlådan som vi ska koppla upp oss till.
  • MAIL_IMAP_PASS- Lösenord (oftast är detta lösenordet från brevlådan).
  • __DIR__- Detta är sökvägen till mappen där bilagor och e-postmeddelanden kommer att sparas.

Efter det kommer vi att kontrollera om vår anslutning skapades genom metoden getImapStream() om anslutningen av någon anledning inte skapas, ger applikationen undantag med anledningen till den misslyckade anslutningen.

Det är viktigt att ta hänsyn till det faktum att i Yandex e-postinställningar kan du ha möjligheten att ansluta med IMAP-protokollet inaktiverat.

Låt oss nu jämföra anslutningen till Gmail-e-post.

Define("MAIL_IMAP_SERVER", "imap.gmail.com"); define("MAIL_IMAP_SERVER_PORT", 993); define("MAIL_IMAP_LOGIN", " "); define("MAIL_IMAP_PASS", "example_pass"); define("MAIL_IMAP_PATH", "(".MAIL_IMAP_SERVER.":".MAIL_IMAP_SERVER_PORT."/imap/ssl)INBOX");

Som vi kan se skiljer det sig praktiskt taget inte från den tidigare anslutningen, men troligen kommer du att få ett undantag när du ansluter till servern.
Detta problem är relaterat till det faktum att Gmail IMAP-protokoll inaktiverat som standard. Du kan aktivera det i inställningarna på fliken Vidarebefordran och POP/IMAP i alternativet IMAP-åtkomst ⇒ Aktivera IMAP.

När vi har aktiverat IMAP-protokollet måste vi göra det skapa applösenord. För att kunna skapa den behöver vi göra en tvåfaktorsauktorisering för denna profil. Sedan kan du börja skapa den. När vi skapar ett nytt lösenord för applikationen måste vi ange det i MAIL_IMAP_PASS-konstanten för att ansluta till servern.

Observera att när du skapar ett applikationslösenord kanske du inte kan ansluta till servern, detta beror på att detta lösenord ännu inte har tillämpats fullt ut på Gmail-tjänsten, vanligtvis tar det 5-60 minuter.

Datasampling

Efter en lyckad anslutning kan vi utföra en begäran om att ta emot strömmeddelanden från servern. För detta kommer vi att använda metoden searchMailBox(sträng $criteria) som i huvudsak är en metodomslag imap_search. Det är viktigt att förstå här att argumentet $criteria är ett visst kriterium för att hitta de meddelanden vi behöver, själva metoden returnerar identifierarna för de element som senare kommer att vara användbara för oss för att få detaljerad information om e-postmeddelandet.

$mailsIds = $mailbox->searchMailBox("ALLA");

Som du kanske har gissat tar vi här emot alla meddelanden.
Och låt oss nu försöka ta itu med andra lika viktiga sökkriterier:

//Alla meddelanden i 3 dagar. $mailsIds = $mailbox->searchMailBox("SEDEN "".date("d-M-Y",strtotime("-3 day"))."""); //Olästa meddelanden i 3 dagar. $mailsIds = $mailbox->searchMailBox("OSIS SEDAN "".date("d-M-Y",strtotime("-3 day"))."""); //Sök efter meddelanden med denna matchning i TEXT-huvudet. $mailsIds = $mailbox->searchMailBox("TEXT "Nyhetsbrev""); //Sök efter meddelanden med denna matchning i BODY-huvudet. $mailsIds = $mailbox->searchMailBox("BODY "Informationsmeddelande""); //Sök på avsändarens e-post. $mailsIds = $mailbox->searchMailBox("FRÅN " ""); //Få meddelanden via SUBJECT header $mailsIds = $mailbox->searchMailBox("ÄMNE "Uppdateringar för din telefon har släppts"");

Detta exempel fångar grunderna för att använda sökkriterier väl.

Tar emot informationen

Nu när vi har en mängd meddelande-ID:n är vi redo att bearbeta det:

//Hämta ID för det senaste meddelandet från arrayen. $id = end($mailsIds); //Hämta en instans av klassobjektet IncomingMail som innehåller information om meddelandet. $mail = $mailbox->getMail($id); //Hämta filerna bifogade till detta meddelande om det finns. $mail->getAttachments(); //Visa meddelanden. echo $mail->textHtml;

Så vi fick meddelanden från vårt brev och dess bilagor utan problem.

Ytterligare egenskaper.

Det här biblioteket innehåller också ett antal användbara metoder för enklare arbete med e-postmeddelanden:

Vi sparar meddelanden efter dess id.

$mailbox->saveMail($id,$id.".eml");

Ange meddelanden som olästa av deras id.

$mailbox->markMailAsUnread($id);

Ställ in meddelanden som lästa av deras id.

$mailbox->markMailAsRead($id);

Vi sätter ett märke på meddelandet med dess id.

$mailbox->markMailAsImportant($id);

Ta bort meddelanden efter deras id.

Vissa webbapplikationer kan kräva en specifik e-post för användaren. I ett sådant fall kan vi skriva vår egen SquirrelMail eller Roundcube e-postkod. Oavsett vilket du väljer kommer det att vara bra att veta hur man arbetar med IMAP-post.

Hur man arbetar med IMAP i PHP beskrivs på två sidor. På första sidan, de nödvändiga funktionerna för att ansluta till e-postservrar och läsa meddelanden. På den andra sidan kommer vi att prata om att arbeta med e-post, till exempel, radera meddelanden, ladda ner applikationer, etc...

För att demonstrera funktionaliteten kommer kodexempel att användas som kan användas för att köra inbyggda e-postklientskript.

URL-parametrar för att anropa de nödvändiga funktionerna:

  • func - den typ av funktion som behövs (till exempel: läsa e-post, visa brevlåda, radera meddelande)
  • mapp - brevlådans mappnamn för anslutning (till exempel: Inkorg, Skickat, skräppost)
  • uid - unik e-postidentifierare

Parametrar kan hämtas med $_GET och switch kan användas för att anropa lämpliga åtgärder.

Ansluter till en IMAP-server

För att upprätta en anslutning till IMAP-servern använder vi funktionen imap_connect() som visas nedan:

Meddelandesökvägen, användarnamnet och lösenordet är de parametrar som krävs för att ansluta till servern. Du kan lära dig om ytterligare alternativ i manualen.

Brevlådans sökväg är en sträng som identifierar servern och porten inom parentes anger namnet på den önskade e-postmappen.

Här är några rader för mappen inkorg posttjänster:

  • Gmail (imap.gmail.com: 993/imap/ssl) INBOX
  • Yahoo (imap.mail.yahoo.com: 993/imap/ssl) INBOX
  • AOL (imap.aol.com: 993/imap/ssl) INBOX

Vissa servrar har inte SSL aktiverat, i så fall måste du utelämna "SSL" från raden. Andra servrar kan använda sina egna certifikat, i vilka du måste inkludera "NOVALIDATE-CERT".

Med e-postserveranslutningen öppen kan vi nu ta en titt på funktionerna som används för följande aktiviteter:

  • Visa en postlådemapplista i ditt e-postkonto
  • Visa en lista med e-postmeddelanden i en mapp
  • Visa innehållet i en författares e-postmeddelande

E-postmappar

inkorg , Skickat , Sopor Och Spam– Dessa mappar är synliga i nästan alla e-postkonton, och användare kan ofta skapa sina egna mappar. För att kunna se meddelanden i dessa mappar måste vi ändra vår anslutningssträng. Till exempel, använd "INBOX" (Inkorg) i sökvägssträngen tidigare. Om du behöver ansluta till din skräppostmapp, använd något som "Spam" istället. Men medan det kan vara listat som Spam till ett e-postkonto, när det visas via en e-postklient, kan det faktiska namnet på mapparna i bakgrunden vara annorlunda. Vi kan lista alla befintliga mappar i ett konto med imap_list() .

"; foreach ($folders som $folder) ( $folder = str_replace("(imap.gmail..php?folder=" . $folder . "&func=view">" . $folder . ""; ) echo "";

Vi måste skicka anslutningshandtaget som erhålls från imap_open() som initial parameter till imap_list() . Vi måste också skicka sökvägen (utan mappen, till exempel "INBOX"). Begär alla tillgängliga mappar som den tredje parametern.

Meddelandemeddelande

Varje mapp innehåller en lista över tillgängliga e-postmeddelanden, så låt oss se hur vi kan skapa en lista med meddelanden i vår brevlåda.

Först måste du få antalet meddelanden som är tillgängliga med imap_num_msg() . Vi kan sedan använda funktionen imap_header() för att få information om rubriken för varje meddelande.

Låt oss säga om vi vill ha de senaste 20 mejlen:

($numMessages - 20); $i--) ( $header = imap_header($imap, $i); $fromInfo = $header->from; $replyInfo = $header->reply_to; $details = array("fromAddr" => (isset($ fromInfo->mailbox) && isset($fromInfo->host)) ?$fromInfo->mailbox ."@" .$fromInfo->host: "", "fromName" => (isset($fromInfo->personal)) ?$fromInfo->personal: "", "replyAddr" => (isset($replyInfo->mailbox) && isset($replyInfo->host)) ?$replyInfo->mailbox . "@" . $replyInfo->host : "", "replyName" => (isset($replyTo->personal)) ? $replyto->personal: "", "subject" => (isset($header->subject)) ? $header->subject : "", "udate" => (isset($header->udate)) ? $header->udate: ""); $uid = imap_uid($imap, $i); echo "

    "; eka"
  • Från:" . $details["fromName"]; echo " " . $details["fromAddr"] . "
  • "; eka"
  • Ämne:" .$details["ämne"] ..php?folder=" . $mapp. "&id=" . $uid ..php?folder=" . $folder . "&uid=" . $uid . "&func=delete">Ta bort
  • "; eka"
"; }

$Imap-anslutningar måste öppnas i rätt mapp. Vi kan sedan gå igenom de senaste 20 e-postmeddelandena med hjälp av antalet meddelanden som tagits emot av imap_num_msg() . Länken och e-postnumret ges till imap_header() för att få rubrikinformation, som sedan kan misstas för intressant information från avsändaren, e-postadress, namn, ämne osv.

Observera att e-postnumret från det totala antalet meddelanden inte är en unik identifierare för meddelandet. Om du har 100 e-postmeddelanden i din brevlåda, så kommer det sista numret att vara 100, det föregående blir 99, och så vidare. Om du raderar meddelande nummer 100 och sedan får ett nytt meddelande kommer dess nummer att vara 100.

För att fortsätta med följande steg måste du få en unik identifierare för e-postmeddelandet. Varje e-postmeddelande har ett unikt ID som heter UID som vi kan få genom att tillhandahålla e-post, funktionen för nummer imap_uid() UID är unik och kommer inte att förändras över tiden.

Visa innehållet i ett meddelande

Att läsa e-post är inte riktigt lika lätt som de tidigare uppgifterna, så du måste använda Mail Classes som utvecklats av Mitul Koradia. Klassen anpassade följande tre funktioner för vårt exempel nedan:

kodning) (fall 3: return imap_base64($text); fall 4: return imap_qprint($text); standard: return $text; ) ) // multipart if ($struktur->typ == 1) ( foreach ($struktur ->delar som $index => $subStruct) ( $prefix = ""; if ($partNumber) ( $prefix = $partNumber . "."; ) $data = get_part($imap, $uid, $mimetype, $ subStruct, $prefix .($index + 1)); if ($data) (retur $data; ) ) ) ) returnerar falskt; ) funktion get_mime_type($structure) ( $primaryMimetype = array("TEXT", "MULTIPART", "MESSAGE", "APPLICATION", "AUDIO", "IMAGE", "VIDEO", "OTHER"); if ($struktur ->subtype) ( return $primaryMimetype[(int)$structure->type] . "/" . $structure->subtype; ) returnera "TEXT/PLAIN"; )

GetBody()-funktionen hämtar innehållet i e-postmeddelandet genom att skicka in dess UID och IMAP-anslutning. Inuti funktionen anropar vi funktionen get_part() med innehållstypen som text / HTML. E-postmeddelanden med vanlig text är mycket lättare att läsa. Så vi försöker först hitta HTML-innehållet i e-postmeddelandet.

Vi läser sedan e-poststrukturen med funktionen imap_fetchstructure() . Vi har ändrat biblioteksfunktionerna för att använda UID istället för att skicka FT_UID hela tiden.

Sedan får vi MIME-typen för e-postmeddelandet med hjälp av get_mime_type()-funktionen. Det finns åtta MIME-typer som returneras av denna funktion som heltal:

  • 0-TEXT
  • 1 - MULTIPART
  • 2 - MEDDELANDE
  • 3 – ANSÖKAN
  • 4-LJUD
  • 5 - BILD
  • 6 - VIDEO
  • 7-ÖVRIGT

Vi omvandlar returen till den faktiska MIME-typen för strängen med hjälp av arrayer av MIME-typer.

Sammansatta meddelanden kan ha ett stort antal undertyper, så vi går rekursivt igenom alla undertyper med hjälp av nummerdelen och hämtar e-postmeddelandet med imap_fetchBody() när den korrekta hittas med mime-typen.

Sedan använder vi lämplig avkodningsfunktion enligt meddelandetypens kodning och returnerar innehållet. Fullständig lista över tillgängliga kodningstyper:

  • 0-7 bitar
  • 1-8 bitar
  • 2-BINÄRT
  • 3-BASE64
  • 4 - CITERAD-UTSKRIVBAR
  • 5-ÖVRIGT

Slutsats

Vi har gått igenom grunderna för att ansluta till en IMAP-server, lista meddelanden i tillgängliga mappar och läst klart innehållet i ett e-postmeddelande. På nästa sida i inlägget kommer vi att prata om funktionerna som kan användas för att implementera ytterligare funktioner i e-postklienten, som att ta bort meddelanden och bearbeta bilagor.

Om du upptäcker ett fel, välj en textbit och tryck på Ctrl + Retur
DELA MED SIG: