Какъв е правилният начин за конфигуриране на уникални имейл адреси за всеки потребител, които всички препращат към php скрипт?

Имам уеб приложение с прибл. 30 хиляди потребители и расте бързо. Искаме да активираме някои функции по имейл, което означава задаване на уникален имейл адрес на всеки потребител (от съображения за сигурност). Имейлите, изпратени до тези уникални адреси, трябва да бъдат препратени към PHP скрипт. PHP скриптът се нуждае от достъп до всички части на имейла - заглавките, тялото и всички прикачени файлове. Не съм сигурен какъв е правилният начин да настроя това. В момента използваме sendmail и бихме предпочели да се придържаме към него (това е linux, ако има значение). Успях да получа индивидуално препращане на имейл към скрипт, но не е мащабируем (според мен) за създаване на 30k псевдоними и след това нов всеки път, когато нов потребител се регистрира. Бих бил много по-доволен от някакъв тип решение за обхващане на всичко / базирано на RegEx, което просто казва на PHP скрипта уникалния имейл адрес, който е бил получателят, което би ни позволило да търсим потребителя.


person Dave    schedule 06.09.2012    source източник


Отговори (3)


30k акаунти не ни дават информация за трафика, който очаквате да обработите. Но да приемем, че е друг въпрос.

Бихте могли да създадете catch all тип акаунт, който просто ще приема всеки имейл в домейна, в който създавате адресите на вашите потребители (основно *@domain). След това можете да стартирате своя скрипт за обработка на всяка входяща поща (обикновено бихте могли да извлечете целия текст на пощата от stdin поток (в PHP, достъпен чрез php://stdin), и да го обработите, както желаете. Но това е лошо, ако искате да използвате PHP (или почти всеки скриптов език), тъй като всяка поща ще трябва да създаде нов PHP процес, да инициира всички разширения и т. н. Всичко това отнема време и ресурси и едно по-голямо наводнение от спам и кутията ви е почти препечена.

Като алтернатива можете да събирате пощата си в пощенската кутия като всяка друга поща и след това вашият скрипт да я получава оттам (или директно, копаейки в maildir, или чрез пощенски протоколи като IMAP или POP). Това изглежда по-добре от гледна точка на администрацията и докато вашият мейл сървър може да приема входящи имейли, цялата ви система все още работи. Можете дори да опитате да "разделите" системата си, като зададете някои правила за филтриране (на ниво MTA) и доставяте входящите имейли не до една пощенска кутия, а повече. Тогава можете да обработвате тези имейли паралелно с по-малко проблеми (няма нужда да се притеснявате да обработвате една и съща поща с повече от един екземпляр и т.н.). Схемата за "разделяне" може да бъде абсолютно всякаква, т.е. в зависимост от вашата схема за именуване на пълния адрес, ако е базирана на букви, ще бъде отделна пощенска кутия за a*@, b*@ или [a-d]*@] (зависи от трафика), няма особено значение.

Като алтернатива можете да опитате да поставите телата на входящите имейли в базата данни и след това да ги обработите, както е описано по-горе, без никаква нужда от POP/IMAP обработка.

Каквото и да изберете, препоръчвам НЕ да поставяте вашия скрипт за обработка от каквато и да е форма директно във веригата на процеса за получаване на поща. Обикновено не е проблем да имате 1 минута забавяне (така че можете да имате всякакъв вид демон, работещ и извличащ имейли за обработка, cronjob и т.н.), потребителите могат да чакат толкова много, без да се оплакват - изглежда, че незабавната обработка най-вероятно не е задължително и във вашия случай. Но ако е така, опасявам се, че PHP може да не е най-добрият избор на инструмент.

РЕДАКТИРАНЕ: (за да отговорите на въпрос за коментар и да не достигнете ограничението за размер на коментара)

Не съм достатъчно запознат със Sendmail, за да ви дам точни указания за конфигурация тук (аз съм с персонализиран qmail), но някои общи съвети, надявам се, ще са приложими. Първо, вярвам, че Sendmail поддържа виртуални потребители (което означава пощенски кутии за потребители, които не присъстват в /etc/passwd). Ако е така, тогава MTA обикновено трябва да ви позволи или да правите заявки в DB (за да разберете дали целевият имейл адрес е валиден и къде е домашният каталог на този потребител, в който да поставите поща) с някои вградени доставчици. Или (което е дори по-добре) извикайте външна програма, за да направите това. Последният е победител тук, защото всъщност няма потребители, така че можете да напишете малък скрипт или (отново, по-добро за производителност) C приложение, което ще свърши работа. Тъй като всичко, от което се нуждаете, е да „разделите“ входящите имейли в няколко физически пощенски кутии въз основа на някои прости предварително дефинирани правила, няколко if()s + substr()s и сте готови. Няколко реда, не е необходима DB, доста бързо. Или, още по-добре, можете дори да опитате най-глупавия roundrobin подход и тук - всъщност е без значение дали имейлът достигне accountA или accountB, стига 50% от имейлите да завършват на A, а останалите 50% на B (или 25%, ако вие отидете на 4 целеви акаунта и т.н.) и това е единственото условие, което трябва да ви интересува според мен. Можете да опитате да използвате procmail за това, но мисля, че е безсмислено и не е най-доброто за производителност.

Що се отнася до поставянето на имейли в база данни. Зависи от MTA - по подразбиране никой не го прави, тъй като е по-бавно от поставянето на имейли в maildirs (тъй като DB обикновено е друг хост), но все пак има няколко решения. Или потърсете пачове на трети страни за Sendmail, които правят това, или добавете друг скрипт/приложение, което да „копира“ имейли от физически пощенски кутии в DB. Може да кажете - но ще бъде по-бавно. Разбира се, но отново - не знам дали обработката извън реално време наистина има значение във вашия случай (моето сляпо предположение - няма), така че защо наистина да се притеснявате. Ако спестите няколко милисекунди тук, но загубите минути за по-нататъшна поддръжка на цялото решение, тогава изборът е съвсем очевиден.

Между другото: за всеки случай - винаги, когато написах mailbox, определено имах предвид контейнер за имейли на потребителите, НЕ файлов формат mailbox. Що се отнася до файловия формат maildir (или нещо производно) е много, много по-добър избор.

person Marcin Orlowski    schedule 10.09.2012
comment
Определено вярно. Акаунтът „catch all“ е далеч най-доброто решение. - person Alain Tiemblo; 11.09.2012
comment
Това изглежда има смисъл. Знаете ли повече за това как да разделите системата с sendmail и да създадете правила за филтриране? Може ли това да се направи с някакъв тип RegEx? Това би било идеалното решение. Като алтернатива, какво имате предвид, когато казвате, че можете да поставите входящата си поща в DB и след това да я обработите? Как бих могъл да направя това, без пряко да участвам PHP скрипт? - person Dave; 11.09.2012

Наистина ли искате да отделяте PHP за всеки входящ имейл? Това може да ви излезе скъпо, ако имате работа с приличен обем поща. Защо да нямате персонализирано обратно извикване във вашия пощенски сървър, който обработва входящата поща и вмъква в база данни, а след това да имате работен скрипт, който непрекъснато търси нови съобщения за обработка?

Частта mail-to-db трябва да е много по-лека от извършването на цялата обработка и това ви дава безплатна опашка, така че ако получите куп заявки почти по едно и също време, системата ви да не падне, опитвайки се да обработи всички наведнъж.

person Tyler Eaves    schedule 10.09.2012

направи подобна реализация на това, макар и в по-малък мащаб... все пак трябва да се мащабира, за да отговори на вашите цели.

два отделни проблема

(1) поща - catch-all, както беше споменато, е добро решение, въпреки че ще трябва да се справите със спам и неправилно формирани имейл адреси (което може да е нещо добро или лошо). Ако притежавате сървъра, просто задаване на псевдоним на „фиктивните“ акаунти и насочване на имейл сървъра да ги пусне всички в една и съща централна пощенска кутия ще изпълни задачата, тъй като не се нуждаете от отделни действителни акаунти и информацията в заглавката ще остане непокътната. спецификата зависи от вашето решение за поща, но всеки пощенски сървър трябва да е повече от оборудван да се справи с тази задача и обема и трябва да можете да скриптирате създаването на псевдоним... в противен случай се върнете към всички

(2) PHP разбор и обработка – вградените pop3 функции на PHP могат лесно да се справят с проверката на (сега) един имейл акаунт и обработката на съобщенията; Някои примери за функции, през които преминавах, са;

function pop3_login($host,$port,$user,$pass,$folder="INBOX",$ssl=false){
        $ssl=($ssl==false)?"/novalidate-cert":"";
        return (imap_open("{"."$host:$port/pop3$ssl"."}$folder",$user,$pass,OP_SILENT));
}
function pop3_stat($connection){
        $check = imap_mailboxmsginfo($connection); # changed from $imap
        return ((array)$check);
}
function pop3_retr($connection,$message,$section='1'){
        return(quoted_printable_decode(imap_fetchbody($connection,$message,$section)));
}
function pop3_dele($connection,$message){
        return(imap_delete($connection,$message));
}
function pop3_close($connection){
        return(imap_close($connection,CL_EXPUNGE));
}

всичко е много общо и вероятно има класове, ако не се нуждаете от контрола. В крайна сметка PHP има всичко необходимо за бързо анализиране и обработка на имейл съобщения.

person Dave    schedule 14.09.2012