[PHP] Mailinglist; mail() of fsockopen()?

Pagina: 1
Acties:
  • 115 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • apNia
  • Registratie: Juli 2002
  • Laatst online: 17-09 22:12

apNia

Schreeuwen en Nibbits eten!

Topicstarter
Op het moment moet ik een mailinglist maken. Aangezien dit via een grote mySQL dbase gaat gebeuren weet ik niet hoe verstandig het is dit via een for- of do/while loop te doen (alhoewel na searchen hier ik 't idee kreeg dat dat nog wel meeviel). En aangezien in de mails de naam moet komen van de persoon is een BCC geen optie.

Anyways, in de meer "profi" scriptjes (nee ik ben niet van plan te gaan rippen, maar te leren ;)) zie ik dat fsockopen() wordt gebruikt ipv mail(). Is dit nou echt verstandiger, en wat zou de reden zijn dat ik fsockopen() boven mail() verkies?

Acties:
  • 0 Henk 'm!

  • twiekert
  • Registratie: Februari 2001
  • Laatst online: 30-08 11:55
ik weet niet zoveel van de werking van de mail() functie en al helemaal niet van de fsockopen functie maar in denk dat het zo zit:

mail is een functie die contact maakt met mailserver, mail verstuurd naar de server, connectie afsluit.


fsockopen biedt de mogelijkheid om handmatig een connectie te openen met de mailserver, verschillende mails te gelijk op te maken en in 1 keer te versturen naar de mailserver.

dus je hebt 1 open connectie voor meerdere mails ipv connectie openen / afsluiten per e-mail bij gebruik van de mail() functie.

toch :?

Acties:
  • 0 Henk 'm!

Verwijderd

Ik heb ook ooit zoiets gemaakt. Script werkt perfect, maar als er iets verstuurd moet worden naar > 50 mensen, dan duurt het dus lang voordat de pagina geladen is. Ik heb gebruik gemaakt van mail(). Is het zo dat fsockopen() dit probleem oplost?

Acties:
  • 0 Henk 'm!

  • Liqued
  • Registratie: Februari 2001
  • Laatst online: 06-08 15:21
fsockopen() wordt gebruikt om connecties in het algemeen te maken. Je moet daarna de verbinding zelf helemaal regelen. Het voordeel hiervan is dat het heel dynamische is en je alles zelf kan maken.

mail() is een voorgeprogrammeerd stukje waardoor je makkelijk mails kan versturen. Je kan zeggen dat mail() een specifieke uitbreiding op fsockopen() voor mailen is. Ik zelf zou als ik niet al te raren dingen nodig zou hebben gewoon mail() gebruiken.

Acties:
  • 0 Henk 'm!

  • Insano
  • Registratie: Juni 2001
  • Laatst online: 06-12-2021
zowiezo het mailen niet met php laten gebeuren, duurt veel te lang, en is te zwaar. Ook ga je gillen als je browser hangt, of je verbinding ineens weg is.
ik heb voor het bedrijf waar ik werk ook een mailer gemaakt, en die maakt gebruik van een daemon die op de server draait, die een apparte que table uitleest.

dus het opdracht geven van +/- 80.000 mailtjes duurt voor mij 10 seconden.. :) en dan handelt die daemon het verder af.. dus er word ook niet steeds een HTTPD thread gestart voor ELK MAILTJE :X

om hoeveel 'members' in die lijst gaat het dan?

[ Voor 24% gewijzigd door Insano op 17-07-2003 14:57 ]


Acties:
  • 0 Henk 'm!

  • apNia
  • Registratie: Juli 2002
  • Laatst online: 17-09 22:12

apNia

Schreeuwen en Nibbits eten!

Topicstarter
Ik gok dat het niet meer dan 80.000 gaan zijn. Probleem is een beetje dat het wel webbased MOET. En als mail() inderdaad een uitbreiding is van fsockopen die opent,send,closed dan is dat met (ik-noem-maar-wat) 80.000 users natuurlijk wel een hoop meer processing dan nodig. Maar in principe is 10 seconden dus maar nodig voor zo'n 80.000 users?

Edit: of komt dat door je maildaemon?

[ Voor 7% gewijzigd door apNia op 17-07-2003 15:00 ]


Acties:
  • 0 Henk 'm!

Verwijderd

DSC schreef op 17 July 2003 @ 14:55:
zowiezo het mailen niet met php laten gebeuren, duurt veel te lang, en is te zwaar. Ook ga je gillen als je browser hangt, of je verbinding ineens weg is.
ik heb voor het bedrijf waar ik werk ook een mailer gemaakt, en die maakt gebruik van een daemon die op de server draait, die een apparte que table uitleest.

dus het opdracht geven van +/- 80.000 mailtjes duurt voor mij 10 seconden.. :) en dan handelt die daemon het verder af.. dus er word ook niet steeds een HTTPD thread gestart voor ELK MAILTJE :X

om hoeveel 'members' in die lijst gaat het dan?
Kijk, zoiets zoek ik dus ook. Probleem is dat ik geen volledige controle heb over de webserver. Zit er dan niets anders op dan toch mail() te gebruiken?

ps. bij mij gaat het om > 500 mailtjes -> 20 seconden

Acties:
  • 0 Henk 'm!

  • Insano
  • Registratie: Juni 2001
  • Laatst online: 06-12-2021
het komt door die mail daemon die er staat.. kijk ik geef gewoon een opdracht om een selectie uit mn memberlijst (of de hele memberlijst) in de que te zetten..

en die query uitvoeren duurt niet echt snel. en die daemon 'pollt' gewoon 24/7 de mail_que table, en kijkt of er een mailtje instaat, zo ja, dan mailt ie em en verwijderd ie em.. net zolang tot de tabel weer leeg is. :)

Helaas kan ik niet die daemon zomaar gaan weggeven, want tis van et bedrijf.
maar voor de mensen die ene beetje handig zijn, kunnen ze et ook maken..

waarvoor zijn die mailinglists eigenlijk?

Acties:
  • 0 Henk 'm!

Verwijderd

De snelheid waarmee je mail() gebruikt ligt aan hoe je PHP hebt ingesteld. Wanneer je gebruik maakt van een lokale MTA zoals Sendmail, zal alle mails worden doorgegeven aan Sendmail en die lost het verder op (korte parsetime).
Wanneer je gebruikt maakt van een SMTP host adres of fsockopen(), maak je een verbinding met een externe MTA. Dit kost natuurlijk tijd en de verbinding zal open blijven staan totdat alle mails zijn aangekomen op de externe MTA (lange parsetime).

Het scriptje waar DSC het over heeft, maakt gebruik van de lokale MTA. Conclusie alles gaat veel sneller, maar werkelijkheid doet de MTA er nog een tijdje over om alles kwijt te raken.


Voor de gene die niet weten wat MTA is: Mail Transport Agent. Dit is gewoon SMTP.

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 19:10
De mail-functie opent normaal gesproken helemaal geen netwerkconnecties (behalve onder Windows) maar geeft de mailtjes gewoon door aan sendmail (of een variant daarvan met dezelfde interface). Als je dus een efficiënte sendmail implementatie gebruikt (zoals qmail, bijvoorbeeld) dan lijkt me dat het versturen met mail ook wel goed moet gaan, al zit je natuurlijk wel aan de overhead van een nieuw process per mailtje vast.

Zie verder ook de PHP manual over mail en de user contributions voor een stukje code dat wel van fsockopen gebruik maakt.

Natuurlijk heb je problemen met PHP scripts die lang draaien (waarna de gebruiker op abort of, vervelender, reload gaat rammen) maar het gebruik van fsockopen lost deze problemen niet op; ze worden eventueel alleen beperkt.

Acties:
  • 0 Henk 'm!

Verwijderd

Hmm... maar die controle of er een que is, wanneer wordt die uitgevoerd? Nee, beter nog: HOE wordt deze uitgevoerd? Met een cron-job of iets dergelijks?

Acties:
  • 0 Henk 'm!

  • Insano
  • Registratie: Juni 2001
  • Laatst online: 06-12-2021
mijn mailer daemon geen script, ik bestuur de db met een script, en die daemon werkt daar mee. maar het is idd zo dat hij een eigen MTA op dezelfde bak heeft ja.

alleen als het moet kan je em ook zo maken dat hij een externe SMTP pakt, maar waarom moeilijk doen, als et makkelijk kan.

Acties:
  • 0 Henk 'm!

Verwijderd

Probleem is dat ik maar weinig rechten heb op de server. Hoe zou ik het op kunnen lossen? Misschien in een apart frame iets laden ofzo? Is toch niet echt een oplossing die de schoonheidsprijs verdient :( ;)

Acties:
  • 0 Henk 'm!

  • SPee
  • Registratie: Oktober 2001
  • Laatst online: 17-09 12:10
Zorg dan dat die mail bestand wordt aangeroepen in een aparte frame (of onder de end HTML tag). Zodat de gebruiker eerst de gewenste pagina krijgt en de mail pagina er wat langer over mag doen.

Of dat je gewoon die mail pagina aanroept maar niets terug voor krijgt.

[edit]
Ook moet je ervoor zorgen dat het niet te lang duurt voordat je pagina klaar is. Na zoveel tijd duurt het te lang om te parsen en wordt hij gewoon weggegooid. En heb je misschien niet alle mails verzonden.

[ Voor 29% gewijzigd door SPee op 17-07-2003 15:19 ]

let the past be the past.


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 19:10
Verwijderd schreef op 17 juli 2003 @ 15:08:
Het scriptje waar DSC het over heeft, maakt gebruik van de lokale MTA. Conclusie alles gaat veel sneller, maar werkelijkheid doet de MTA er nog een tijdje over om alles kwijt te raken.
Dat geldt ook bij het gebruik van sendmail (en varianten). Die plaatsen de mailtjes ook eerst in een queue en het duurt dan nog wel even voor de mailtjes allemaal afgeleverd zijn (temeer daar sommige hosts niet altijd bereikbaar zijn en sendmail dus periodisch opnieuw moet proberen de mailtjes te versturen).

Het cruciale verschil zit 'm dus niet zozeer in parse times, denk ik, maar in het feit dat de mail() functie voor elk mailtje een nieuw proces spawned, terwijl je een socketverbinding geopend kunt houden vanuit het PHP proces.

Acties:
  • 0 Henk 'm!

  • apNia
  • Registratie: Juli 2002
  • Laatst online: 17-09 22:12

apNia

Schreeuwen en Nibbits eten!

Topicstarter
Is het niet mogelijk iets te tonen van "Sending mail..." en dan zodra mail() klaar is te laten zien "Done mailing" ? (en ook te zorgen dat ie niet timeout)

Acties:
  • 0 Henk 'm!

Verwijderd

apNia schreef op 17 July 2003 @ 15:20:
Is het niet mogelijk iets te tonen van "Sending mail..." en dan zodra mail() klaar is te laten zien "Done mailing" ? (en ook te zorgen dat ie niet timeout)
Ja! Zoiets ben ik naar op zoek, maar ik weet niet waar ik op moet zoeken. Iets van: 'Na submit, form uitschakelen' ofzo? Iemand tips?

Acties:
  • 0 Henk 'm!

  • Insano
  • Registratie: Juni 2001
  • Laatst online: 06-12-2021
uhm, nou het probleem zit em in het feit, dat als je veel gaat mailen, dan blijft je script parsen..

dus je moet dan al je timeout op 0 zetten.. anders krijg je 'max execution time exceeded'
en verder is het gewoon zwaar irri als jij je pc voor een uur aan moet laten staan om elk mailtje te doen.

kan je niet gewoon zelf een server neerzetten waar je lekker zelf op kan rommelen?

Acties:
  • 0 Henk 'm!

Verwijderd

Nouja... kan wel, maar das beetje irri denkik. Heb liever dat alles op m'n gehuurde webspace staat.

Acties:
  • 0 Henk 'm!

  • Insano
  • Registratie: Juni 2001
  • Laatst online: 06-12-2021
hmm tja, kijk als je zo'n 500 man in je mailinglist heb,
dan is het nog aardig te doen met een while loopie, en mail();
zolang je je timout maar op 0 zet.. en niet je browser killed.. :)

en zodra je grotere mailings moet doen, (ala het formaat wat ik doe) dan moet je toch echt naar andere oplossingen gaan kijken, omdat het gewoon klote is om zolang te wachten..

en idd, de opdracht geven bij mij duurt 10 secs.. en daarna gaat elk mailtje van mySQL via daemon naar MTA (daar staat het dan ook natuurlijk in een que)

maar ik heb er iig geen last meer van, en kan zo er allerlei andere mailings achteraan gooien..

[ Voor 2% gewijzigd door Insano op 17-07-2003 16:06 . Reden: typo ]


Acties:
  • 0 Henk 'm!

Verwijderd

Baal ervan dat ik geen cronjobs kan doen. Iemand enig idee waarop ik moet zoeken als ik een 'submit'-knop wil deactiveren?

Acties:
  • 0 Henk 'm!

Verwijderd

Na submit wordt de nieuwe pagina aangeroepen. De submitte data in de formulier zal niet veel zijn, alleen de aangeroepen script na submit zal veel data versturen.
Dus als je voordat je de mail() functie aanroept.. iets zegt van "Sending mail... Please don't close this window".. zou het goed moeten zitten.

Acties:
  • 0 Henk 'm!

Verwijderd

Verwijderd schreef op 17 July 2003 @ 15:35:
Na submit wordt de nieuwe pagina aangeroepen. De submitte data in de formulier zal niet veel zijn, alleen de aangeroepen script na submit zal veel data versturen.
Dus als je voordat je de mail() functie aanroept.. iets zegt van "Sending mail... Please don't close this window".. zou het goed moeten zitten.
Klopt, zo zou ik het kunnen doen.
Het mooiste is denkik (en ik heb dit al eens eerder gezien) dat de submit-knop veranderd in 'sending...' en uitgeschakeld wordt. Hoe heet dit verschijnsel?

Acties:
  • 0 Henk 'm!

Verwijderd

Dit is in javascript.

Hier iets wat ik zo uit m'n duim trek:

code:
1
2
<input type="submit" value="submit"
  onclick="javascript:this.value='Sending...';this.disabled=true">

[ Voor 21% gewijzigd door Verwijderd op 17-07-2003 15:43 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Wat ik hier boven zeg werkt.

Wat beter en veilig is:
code:
1
2
3
4
<form method="post" action=""
onsubmit="javascript:this.submit.value='Sending...';this.submit.disabled=true">
<input type="submit" name="submit" value="submit">
</form>

Acties:
  • 0 Henk 'm!

Verwijderd

GrunGe, heeft iemand je wel eens verteld dat je 'n schat bent?

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 19:10
Als je een nieuwe pagina opent, staat die hele submit knop er niet meer op, natuurlijk. Er zijn alleen een aantal dingen waar je rekening mee moet houden.

Ten eerste moet je de script timeout op 0 zetten (ik neem aan dat dat kan bij je hosting provider), omdat anders het script vroegtijd afgebroken wordt door PHP.

Ten tweede moet je user abort uitschakelen, zodat je script doorgaat wanneer de gebruiker (of de browser) het request afbreekt of de connectie verloren gaat.

Ten derde wil je de gebruiker op de hoogte houden van wat er gebeurt en daarvoor heb je twee mechanismen nodig. Ten eerste moet je de HTML pagina zo genereren dat je afzonderlijke blokken genereert, die de browser kan renderen voordat de rest van de pagina binnenkomt. Ik geloof dat paragraph-tags dat in zowel Mozilla als Internet Explorer wel goed doen. Ten tweede moet je vanuit PHP je uitvoer naar de gebruiker sturen voordat je een intensieve berekening doet, zodat de gebruiker ziet dat je bezig bent.

Het is ook van belang dat de nieuwe pagina zo snel mogelijk weergegeven wordt, omdat de gebruiker anders in de verleiding komt om nog een keer te submitten (waardoor de mailtjes nogmaals verstuurd worden).

Samenvattend, wordt je script dus zoiets:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
    ini_set('ignore_user_abort', 1);
    ini_set('max_execution_time', 0);
?>
<html>
<head><title>Sending mail</title></head>
<body>
<p>Please wait while sending mail....</p>
<?php
    flush();

    // tijdsintensieve code komt hier
?>
<p>Done!</p>
</html>


(Code is natuurlijk niet getest, dus er kan hier en daar een foutje in zitten.)

[ Voor 8% gewijzigd door Soultaker op 17-07-2003 16:22 ]


Acties:
  • 0 Henk 'm!

  • stekkel
  • Registratie: Augustus 2001
  • Laatst online: 17-09 08:05
Mailen via een fsocketopen kan best efficient indien het gaat om niet persoonlijk geaddresseerde mail. In je to header set je dan gewoon iets van undisclosed recipients:; en vervolgens spreek je je SMTP server aan met fsocketopen. Je zet de verbindinging op en voor iedere ontvanger doe je:
RCPT TO:<ontvanger@domein.bla> (in een for loopje voor iedere ontvanger)
en wanneer je dat hebt afgerond begin je pas met het eigenlijke mailtje te versturen.

Voor achtergrond info: rfc2811

edit:

oops, het gaat dus wel om persoonlijke mail. Lezen is ook een vak apart.

[ Voor 10% gewijzigd door stekkel op 17-07-2003 18:33 ]


Acties:
  • 0 Henk 'm!

  • Skef
  • Registratie: April 2001
  • Laatst online: 17-09 09:49

Skef

Ik scheer.me

Heb je er al aan gedacht dat je evt. ook iets van BCC kan gebruiken? Op zich is 80000 records in een mail zetten, en het vervolgens BCC verzenden niet zo'n probleem d8 ik.

Wordt bij het gebruik van BCC de mailing 1x verzonden, of wordt ie echt hard 80000x verzonden?

"Computer games don’t affect kids: I mean if Pac-Man affected us as kids, we’d all be running around in darkened rooms, munching magic pills and listening to repetitive electronic music."


Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 16:28

Bosmonster

*zucht*

Wat ikzelf doe is sowieso een veld aanmaken in de DB dat aangeeft of een email verstuurd is ja of nee (mocht de verbinding wegvallen) en de email in batches versturen. Je kunt met een redirect bijvoorbeeld met de volgende 100 beginnen (gewoon via url ofzo).

Voordeel van deze methode is dat je ook een soort van counter-balk bij kunt houden die aangeeft hoeveel je hebt verstuurd :) En dus dat de gebruiker ziet dat ie nog bezig is.

[ Voor 3% gewijzigd door Bosmonster op 17-07-2003 16:31 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Er wordt gezegd het duurt te lang en dan sluiten ze de browser en heb je een probleem. Dat verhaal gaat niet op, op het moment dat de request gedaan is dan is er zegmaar geen weg meer terug. Als de browser gesloten wordt gaat het (serverside) script gewoon door. Anders was een infinite loop ook niet zo'n probleem...
Maargoed dat neemt niet weg dat het niet zo gebruiksvriendelijk is.

Wat je misschien het beste kan doen als het lang duurt, een pagina maken waarnaartoe gepost wordt en dan de melding verschijnt: het mailproces is gestart. Evt de gebruiker zijn email adres laten opgeven voor een succesmelding per mail na afronding.
Het uitvoeren doe je door vanuit dit script het echte mailscript uit te laten voeren (LATEN uitvoeren dus rechtstreeks aan php geven of desnoods gewoon via internet de pagina aanvragen, en dus niet includen)

Acties:
  • 0 Henk 'm!

Verwijderd

Skef schreef op 17 July 2003 @ 16:29:
Wordt bij het gebruik van BCC de mailing 1x verzonden, of wordt ie echt hard 80000x verzonden?
BCC gaat in 1 keer, de mailservert mag het dan verder opknappen. Echter de topicstarter heeft al gezegd dat het persoonlijke mails worden en dan gaat dit helaas niet door

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 19:10
Verwijderd schreef op 17 July 2003 @ 16:34:
Er wordt gezegd het duurt te lang en dan sluiten ze de browser en heb je een probleem. Dat verhaal gaat niet op, op het moment dat de request gedaan is dan is er zegmaar geen weg meer terug. Als de browser gesloten wordt gaat het (serverside) script gewoon door.
Uit de PHP manual:
PHP: Connection handling
[..]
You can decide whether or not you want a client disconnect to cause your script to be aborted. Sometimes it is handy to always have your scripts run to completion even if there is no remote browser receiving the output. The default behaviour is however for your script to be aborted when the remote client disconnects.
[..]

Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 16:51
Ik moet binnenkort ook een mailinglist maken, dus volg dit topic zeker...
Ik ben er momenteel over aan het denken om zelf een mailserver op te zetten, dan is het hele probleem opgelost, tenzij ik mij eigen mailserver overbelast natuurlijk ;)

Acties:
  • 0 Henk 'm!

  • apNia
  • Registratie: Juli 2002
  • Laatst online: 17-09 22:12

apNia

Schreeuwen en Nibbits eten!

Topicstarter
Skef schreef op 17 juli 2003 @ 16:29:
Heb je er al aan gedacht dat je evt. ook iets van BCC kan gebruiken? Op zich is 80000 records in een mail zetten, en het vervolgens BCC verzenden niet zo'n probleem d8 ik.

Wordt bij het gebruik van BCC de mailing 1x verzonden, of wordt ie echt hard 80000x verzonden?
apNia schreef op 17 July 2003 @ 14:49:
En aangezien in de mails de naam moet komen van de persoon is een BCC geen optie.
;)

Acties:
  • 0 Henk 'm!

  • RupS
  • Registratie: Februari 2001
  • Laatst online: 17-07 14:45
Enige tijd geleden had ik last van een trage mail() functie op mijn server, dus ik ben toen ook gaan zoeken. Wat ik toen onder andere tegenkwam is dat php icm. sendmail standaard inderdaad wacht todat de mail echt verstuurd is, in plaats van het versturen later te doen, en de mail in queue te gooien...

Nu kan je dat wel meegeven aan de mail functie ("-O DeliveryMode=b" als laatste argument) Ik heb het zelf niet uitgetest (bleek in mijn geval een simpel resolve probleempje te zijn :X ), maar misschien dat je er iets aan hebt :)
Je kan die DeliveryMode ook instellen in de php.ini als je genoeg rechten op de server hebt...

[ Voor 4% gewijzigd door RupS op 18-07-2003 12:55 ]

Pagina: 1