Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> dlugi czas wykonywania skryptu + przekierowanie
andycole
post
Post #1





Grupa: Zarejestrowani
Postów: 71
Pomógł: 1
Dołączył: 14.12.2004

Ostrzeżenie: (0%)
-----


Witam,

Mam skrypt do wysylki mailingu.
Baza maili moich uzytkownikow liczy ponad 22 tysiace, wiec radze sobie tak:

set_time_limit(300);
pobierz 80 maili sposrod tych do ktorych jeszcze nie wyslano
jezeli sa maile to
w petli
wyslij i zapisz, ze wyslano
sleep(3);
header(odswiezenie strony)
jezeli nie ma juz maili
header(strona glowna wysylki mailingu)

I problem tkwi w tym, ze zawsze po ok 3 minutach (+/- 200 sekund) wywala mi w przegladarce:

Kod
Nieprawidłowe przekierowanie
Firefox wykrył, że serwer przekierowuje żądanie tego zasobu w sposób uniemożliwiający jego ukończenie.


Czy po przekierowaniu header czas wykonania skryptu nie liczony jest na nowo?
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
za017
post
Post #2





Grupa: Zarejestrowani
Postów: 6
Pomógł: 1
Dołączył: 28.05.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Przeglądarki blokują powtarzające się polecenia przekierowania, po pierwsze aby uchronić klienta przed "wędrowaniem" po wielu stronach i zbieraniem różnego rodzaju śmieci (cookiesów), a także przed wpadnięciem w nieskończoną pętlę. Zamiast funkcji header po stronie serwera może użyj meta tagu w kodzie odpowiedzi:
  1. <meta http-equiv="refresh" content="1;url=http://adres_skryptu" />

Skrypt może wstawiać ten tag do nagłówka html'a tak długo, aż zostaną wysłane wszystkie maile. Można też użyć ajax, który będzie w pętli wywoływał skrypt tak długo, jak długo zwraca pewną ustaloną wartość: po wysłaniu wszystkich maili skrypt zwróci pusty tekst jako odpowiedź i pętla zostanie przerwana.
Zaletą ajaksowego rozwiązania jest brak migotania strony w oknie przeglądarki i możliwość zrobienia ładnego, w pełni funkcjonalnego paska postępu (wykorzystaj jQuery).

Załączam gotowca (efekt prokrastynacji, czyli poniedziałkowej niechęci do zaplanowanej pracy (IMG:style_emoticons/default/smile.gif) )

Aby sprawdzić działanie wystarczy:
1. umieścić na serwerze dwa pliki: sendmail.php i mailing.html (źródła poniżej),
2. do podkatalogu js wrzucić bibliotekę jQuery http://docs.jquery.com/Downloading_jQuery
3. utworzyć w bazie danych przykładową tabelę:
  1. CREATE TABLE `tbl_mailing` (`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, `mail` VARCHAR(255), `status` ENUM ('waiting','sent'));

i wypełnić ją danymi, lub dodać pole `status` ENUM ('waiting','sent') do swojej tabeli.

Skrypt działający "w tle", realizujący wysyłanie maili partiami, zwracający do klianta informacje o procentowym postępie, lub zakończeniu wysyłki, nazwa skryptu sendmail.php

  1. <?php
  2. define(HOST,'host');
  3. define(USER,'user');
  4. define(PASSWORD,'password');
  5. define(DATABASE,'database');
  6. define(TABLE_MAILING, '`tbl_mailing`');
  7. define(HOW_MANY_EMAILS_AT_ONCE,25);
  8.  
  9. $db = new mysqli(HOST,USER,PASSWORD,DATABASE);
  10.  
  11. // pole `status` jest zdefiniowane jako: `status` ENUM ('waiting','sent')
  12.  
  13. // Ilość wszystkich maili:
  14. $total = $db->query('SELECT COUNT(id) FROM '.TABLE_MAILING)->fetch_row();
  15.  
  16. // pobieramy maile oczekujące na wysłanie
  17. $ans = $db->query('SELECT * FROM '.TABLE_MAILING.' WHERE `status`=\'waiting\' ORDER BY `id` ASC LIMIT 0,'.HOW_MANY_EMAILS_AT_ONCE);
  18. $confirm = array();
  19. while($row = $ans->fetch_row()) {
  20. echo $row[0].':'.$row[1].'<br />';
  21.  
  22. /* -- TUTAJ REALIZUJEMY LOGIKĘ ZWIĄZANĄ Z WYSYŁANIEM MAILI -- */
  23.  
  24. // budujemy listę maili, których wysłanie zakończyło się sukcesem
  25. array_push($confirm, $row[0]);
  26. }
  27.  
  28. if(count($confirm))
  29. $db->query('UPDATE '.TABLE_MAILING.' SET `status`=\'sent\' WHERE `id` IN ('.implode(',',$confirm).')');
  30.  
  31. // Ilość pozostałych do wysłania
  32. $waiting = $db->query('SELECT COUNT(id) FROM '.TABLE_MAILING.' WHERE `status`=\'waiting\'')->fetch_row();
  33.  
  34. // Zwracamy procentowy postęp wysyłania maili lub potwierdzenie zakończenia
  35. if($waiting[0]) {
  36. $sent = $total[0] - $waiting[0];
  37. echo '
  38. <input type="text" id="percent" value="'.(round(100*$sent/$total[0], 2)).'" />
  39. ';
  40. } else
  41. echo '<input type="text" id="finished" value="yes" />';


Frontend dla klienta: nazwa pliku np. mailing.html (oczywiście może być wygenerowany przez php)
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
  3. "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
  4. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="pl">
  5. <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
  6. <meta http-equiv="Content-language" content="pl" />
  7. <script type="text/javascript" src="js/jquery.js" ></script>
  8. <script type="text/javascript">
  9. function loader() {
  10. $.ajax({
  11. type: "GET",
  12. url: "sendmail.php",
  13. cache: "false",
  14. data: "",
  15. success: function(msg) {
  16. $("#data").empty().append(msg);
  17. if($("#finished").val()=="yes") {
  18. // unikamy błędów zaokrągleń i błędu przy odświeżeniu strony:
  19. $("#progressBar").css("width","800px");
  20. alert("Gotowe !");
  21. return;
  22. }
  23. $("#progressBar").css("width", (Math.round($("#percent").val()*8)) + "px" );
  24. setTimeout("loader()",1); // unikamy wywołania rekurencyjnego!
  25. },
  26. handleError: function() { alert("hm..."); }
  27. });
  28. }
  29.  
  30. onload = function() {
  31. loader();
  32. }
  33.  
  34. <style type="text/css">
  35. body { text-align:center; }
  36. div#body { width:900px;margin:0px auto 0px auto; border:1px solid #eee;padding:25px;}
  37. div#container { margin:0px auto 0px auto;width:800px;border:1px solid #000; }
  38. div#progressBar { height:20px;width:0px;background-color:#000066;margin:0px;padding:0px;font:8pt/12pt arial,tahoma,verdana,helvetica; }
  39. </head>
  40. <div id="body">
  41. <div id="container">
  42. <div id="progressBar">
  43. </div>
  44. </div>
  45. </div>
  46. <div id="data" style="display:none"></div>
  47. </body>
  48. </html>


Ten post edytował za017 21.12.2009, 12:10:25
Go to the top of the page
+Quote Post

Posty w temacie
- andycole   dlugi czas wykonywania skryptu + przekierowanie   5.12.2009, 15:57:22
- - darko   Pokaż kod, zgaduję, że robisz przekierowanie do te...   5.12.2009, 16:02:25
- - andycole   Skrypt jest przydlugawy, ale jest jak mowisz, do t...   5.12.2009, 16:04:23
- - darko   set_time_limit ($nowy_czas_w_sekundach) lub i...   5.12.2009, 16:10:23
- - andycole   wczesniej mialem set_time_limit(600); ale nie dzia...   18.12.2009, 00:22:12
- - thek   Ja robię to w sposób "oflagowany". Wybie...   18.12.2009, 09:48:28
- - Pilsener   A po co jakiś header, sleep itp. Nie prościej użyć...   18.12.2009, 10:24:27
- - andycole   Dzieki za konkretne odpowiedzi. Co do flag, zamia...   18.12.2009, 11:40:24
- - Pilsener   Wszystko zależy od tego, czy Twój hosting daje Ci ...   18.12.2009, 12:20:25
- - andycole   Mam VPS'a,   18.12.2009, 12:27:00
- - thek   Pilsener... Pogadaj sobie o Cronie w sytuacji gdy ...   18.12.2009, 13:15:07
- - Pilsener   Ale przecież sam napisałeś Cytatmasz limit skryptu...   19.12.2009, 00:25:41
- - andycole   Dajcie juz spokoj thek, powiedz mi lepiej jak prz...   19.12.2009, 02:33:56
- - darko   Zawsze możesz zrobić jeszcze tak: 1. sprawdzić ile...   19.12.2009, 03:05:41
|- - andycole   Cytat(darko @ 19.12.2009, 03:05:41 ) ...   19.12.2009, 10:46:29
- - Thorang Hoog   Cytat(andycole @ 19.12.2009, 10:46:29...   20.12.2009, 15:11:49
|- - andycole   Cytat(Thorang Hoog @ 20.12.2009, 15:11...   20.12.2009, 15:36:51
|- - jajcarzd1   Cytat(Thorang Hoog @ 20.12.2009, 16:11...   22.12.2009, 11:59:41
- - kacka   Pamiętaj tylko że mailing takiej ilości wiadomości...   20.12.2009, 15:21:49
- - Thorang Hoog   Cytat(andycole @ 20.12.2009, 15:36:51...   20.12.2009, 21:15:14
- - za017   Przeglądarki blokują powtarzające się polecenia pr...   21.12.2009, 08:01:07
- - andycole   za017, "pomógł". Twój pomysł i skrypt po...   22.12.2009, 21:02:24
- - za017   Dzięki za plusik. To duża satysfakcja, że coś zrob...   23.12.2009, 08:41:16


Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 25.08.2025 - 03:19