Avatar billede whyme Nybegynder
30. marts 2005 - 20:40 Der er 24 kommentarer og
1 løsning

Send en e-mail efter 1 uge og efter 2 uger slettes mail fra tabel

Hej Eksperter,

Jeg har en while() løkke hvor jeg sender en e-mail til en masse tilmeldte e-mail som jeg har i en tabel via:

mail($sendto, $subject, $content, $headers);

Jeg har med hver e-mail gemt tiden i sekunder med time() i tabellen med tiden for oprettelsestidspunktet.

Det jeg godt kunne tænke mig er hjælp til at lave et lille regne stykke hvor den siger:

Hvis ($tiden_i_tabel er over 7 dage gammel men mindre end 14 dage gammel) {
send en e-mail
} ellers hvis ($tiden_i_tabel er over 14 dage gammel) {
slet e-mail i tabellen
}

På forhånd mange tak
Avatar billede bromer Nybegynder
30. marts 2005 - 20:56 #1
Logisk set skal du gøre det i omvendt rækkefølge. Du starter med at slette alle rækker der har kolonnen "tid" større end 14 dage med denne query:

mysql_query("DELETE FROM <dintabel> WHERE DATE_SUB(NOW(), INTERVAL 14 DAY) > tid");

Så ved du med sikkerhed at alle rækker med tid større end 7 dage ligger i netop det interval du gerne vil sende mails til. Dem finder du så ved

mysql_query("SELECT * FROM <dintabel> WHERE DATE_SUB(NOW(), INTERVAL 7 DAY > tid");

--
Rune Bromer
Avatar billede whyme Nybegynder
30. marts 2005 - 22:14 #2
Hvad er dette for noget?
DATE_SUB(NOW(), INTERVAL 7 DAY

Den kender jeg ikke.

Jeg har i min tabel alt tiden i sekunder... eksempelvis tid-feltet som hedder "dato" indeholder "1112202820".

Hvordan regner jeg med den? vil det du har skrevet også virke, eller skal den skrives anderledes?
Avatar billede bromer Nybegynder
30. marts 2005 - 22:18 #3
Det jeg har skrevet gør brug af MySQLs datesub funktion. Det er generelt dumt at have tiden gemt i UNIX timestamps i en database fordi man hellere vil have at databasen kan genkende data som datoer og behandle det som så. Antaget du har det i sekunder burde du kunne bruget noget af det her:

$week = 60*60*24*7;
$deletetime = time() - 2*$week;
mysql_query("DELETE FROM <dintabel> WHERE tid < " . $deletetime);

$selecttime = $deletetime = time() - $week;
mysql_query("SELECT FROM <dintabel> WHERE tid < " . $selecttime);
Avatar billede whyme Nybegynder
30. marts 2005 - 22:22 #4
bromer:
Denne virker ikke:

$get_all_emails = mysql_query("SELECT * FROM emails WHERE active = 'no' AND (DATE_SUB(NOW(), INTERVAL 7 DAY) > tid) LIMIT 0,10");
Avatar billede whyme Nybegynder
30. marts 2005 - 22:22 #5
Kigger lige på det du skrev, så det først nu
Avatar billede bromer Nybegynder
30. marts 2005 - 22:23 #6
det jeg skrev tidligere virker kun når kollen tid er en form for MySQL tid
Avatar billede whyme Nybegynder
30. marts 2005 - 22:25 #7
Hvorfor siger du at selecttime er lig deletetime og lig time()-week? skal deletetime ikke væk fra nr. 2 ligning?
Avatar billede bromer Nybegynder
30. marts 2005 - 22:26 #8
jo.. deletetime skal væk.. det var mig der var lidt for hutig med at paste
Avatar billede whyme Nybegynder
30. marts 2005 - 22:29 #9
Kan du lige sige hvad der er galt her?
$get_all_emails = mysql_query("SELECT FROM emails WHERE active = 'no' AND tid < $selecttime LIMIT 0,10");

Får fejlen:

Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in /var/www/inc/header.inc.php on line 20
Avatar billede bromer Nybegynder
30. marts 2005 - 22:32 #10
ja.. du har ikke valgt noget i din select :)
Avatar billede whyme Nybegynder
30. marts 2005 - 22:41 #11
Denne virker heller ikke:
$get_all_emails = mysql_query("SELECT * FROM emails WHERE active = 'no' AND tid < $selecttime");
Avatar billede bromer Nybegynder
30. marts 2005 - 22:46 #12
og hvilken fejlbesked får du når du udfører:

$get_all_emails = mysql_query("SELECT * FROM emails WHERE active = 'no' AND tid < $selecttime") OR DIE(mysql_error());
Avatar billede whyme Nybegynder
30. marts 2005 - 22:49 #13
Det ser ud til at virke nu...

Men for at være helt sikker (der er jo 500+ emails) hvordan kan jeg så være sikker på at den virker som den skal?

Slet emails som er over 14 dage
Send en e-mail ud til dem som er over 7 dage
Avatar billede bromer Nybegynder
30. marts 2005 - 23:00 #14
jeg ville lave ny ny tabel med samme struktur og så indsætte din egen mail ind med forskellige timestamps og se hvordan du modtager mailsene
Avatar billede bromer Nybegynder
01. april 2005 - 15:01 #15
Fik du det nogensinde til at virke?
Avatar billede whyme Nybegynder
01. april 2005 - 22:54 #16
Jeg synes ikke rigtigt at det virker helt optimalt når jeg prøver at ændre timestamp... hvis jeg skal teste "rigtigt", hvordan skal jeg så sige?

time()-(60*60*24*7) // tiden nu minus 1 uge

Er det den tid jeg skal ændre et felt i mysql databasen til, for at teste?
Avatar billede bromer Nybegynder
01. april 2005 - 23:02 #17
Hvis du gør det så vil beskeden blive valgt af den select. Hvis du sætter dit felt til "time()-(60*60*24*7*2) så vil den blive slettet når du kører scriptet.
Avatar billede whyme Nybegynder
02. april 2005 - 12:26 #18
Ja, det ser sgu ud til at virke, kan du komme med et svar?

En anden ting... jeg skal kunne sende ud til eks. 10.000 eller 20.000 email adresser med PHP's mail() funktion. Hvad er smartest at gøre, så man kan sende til dem alle uden timeout?
Avatar billede bromer Nybegynder
02. april 2005 - 13:37 #19
Du skal helt sikkert sætte PHP timeout højere når det er så mange mails. Hvis du sender flere mails ved "mail("email1,email2","subject","content")", så må du ifølge SMTP specifikationen kun sende til 100 adresser af gangen".
Avatar billede whyme Nybegynder
02. april 2005 - 13:45 #20
Hvordan bliver dette så gjort rent praktisk?

Hvis du kan hjælpe mig til noget konstruktivt, opretter jeg et spørgsmål du lige kan svare på, så får du lige 150 points igen :)
Avatar billede bromer Nybegynder
02. april 2005 - 13:48 #21
tak for point. Hvad er det du vil undrer dig over hvordan man gør praktisk?
Avatar billede whyme Nybegynder
02. april 2005 - 13:51 #22
Hvis jeg har eks. 20.000 e-mails i en tabel med:

name,email


Så vil jeg gerne lave en form for

while ($noget) { // send til 20.000 emails
  indhold af emails
  mail() // send til email
}

Noget ala det, men kun 100 e-mails af gangen, eller noget i den stil... altså den "sikre" måde så jeg er sikker på de bliver afsendt m.v.
Avatar billede bromer Nybegynder
02. april 2005 - 14:11 #23
Okay. Det jeg normalt gør når jeg på et site skal sende rigtig mange mails ud er at have følgende tabel:

create table mails (
  id integer auto_increment primary key,
  mail_to varchar(255) not null,
  subject text,
  content text,
  headers text,
  send_by datetime,            -- Mailen må først sendes efter denne dato...
  sent enum('n','y') DEFAULT 'n'
);

så ville jeg løbe dine mails igennem med

while($noget) {
  // insert into mails tabellen
}


Hvis du så hver gang du skal sende en mail istedet smider den ned i tabellen får du faktisk et hurtigere system idet PHP er langt hurtigere til at smide en række i en tabel end til at sende en mail. Derudover får du også et centralt register for alle de mails du nu engang sender ud til folk. Derudover plejer jeg også at have tabellen:

create table nospam (
email  varchar(255) not null primary key
);


Det sidste du så mangler er et script der sender mails ud fra tabellen. Det kan du lave med følgende kode..

<?
$rs = mysql_query("select id,mail_to,subject,content,headers,email FROM mails LEFT JOIN nospam ON (email = mail_to) WHERE email IS NULL AND send_by < NOW() AND sent = 'n' LIMIT 50");

while($row = mysql_fetch_row($rs)) {
        mail($row['mail_to'],$row['subject'],$row['content'],$row['headers']);

        // update and set the sent enum field to sent
        mysql_query("update mails SET sent = 'y' WHERE id = " . $row['id']);
}
?>

Den sender så kun 50 mails ud og det kan den sagtens nå. Du vil så gerne sætte dette script i cron så det bliver kørt hvert 2 minut eller hvad der nu passer det til load dit system har. Hvis du ikke har kontrol over serveren kan du benytte noget webcron [1], hvor deres system "rammer" din side udfra en eller anden cyklus.

[1] http://www.webcron.org
Avatar billede whyme Nybegynder
02. april 2005 - 14:59 #24
Jeg kan godt tilføje feltet "sent" i min tabel, og så sætte det til "y" når posten er sendt, og sætte LIMIT til 50, og køre det hver 2 min.

Men eks. skal det være i administrationen at man vælger "Send nyhedsbrev til" <Drop down boks>

Hvor i drop down kan der stå eks.:

100
500
1000
5000
10000

e-mails

Efter valg, trykker man submit, og den skal sende e-mails til eks. 5000 "random" e-mails fra tabellen...

Det kan man jo ikke lave en "statisk cron" som sådan til... det er lidt tricky... uhm... :)
Avatar billede bromer Nybegynder
02. april 2005 - 15:03 #25
Det er da overhoved ikke noget problem. Mail tabellen er rimelig dum og lige til. Når man smider en række deri bliver der sendt en mail. Så hvis du sætter det op og får noget cron til at besøge den i en cyklus så er det jo bare en anden måde at sende mails på. Hvis du har antallet af emails du vil sende ud i $count kan du gøre følgende:

$rs = mysql_query("SELECT <emailfelt> FROM <tabelnavn> ORDER BY RAND() LIMIT " . $count);
while($row = mysql_fetch_array($rs)) {
  // insert denne email i tabellen og vent på at cron sender den
}
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester