Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [klasa] mailing
piotrooo89
post
Post #1


Newsman


Grupa: Moderatorzy
Postów: 4 005
Pomógł: 548
Dołączył: 7.04.2008
Skąd: Trzebinia/Kraków




dziękuje za wszelkie porady, uwagi. zabieram się do poprawek.

proszę również o dalsze komentarze.

Odłożyłem na chwile stronicowanie, potrzeba chwili wymogła na mnie zrobienie newslettera. Nie chce zakładać kolejnego tematu więc pokaże go tu. Jest to najprostsze wysyłanie maila, tymczasowo bez nagłówków. Powiedzcie mi czy idę w dobrą stronę.

newsletter-class.php
  1. <?php
  2. class Newsletter
  3. {
  4.    public function GetMailsFromFile($file, $separator)
  5.    {
  6.        $string = file_get_contents($file);
  7.        $mails_file = explode($separator, $string);
  8.        return $mails_file;
  9.    }
  10.    public function GetMailsFromDb($sql)
  11.    {
  12.        $sql_query = mysql_query($sql);
  13.        while ($rows = mysql_fetch_row($sql_query))
  14.        {
  15.            $mails_db[] = $rows[0];
  16.        }
  17.        return $mails_db;
  18.    }
  19.    public function Send($where, $subject, $message)
  20.    {
  21.        foreach($where as $mails)
  22.        {
  23.            mail($mails, $subject, $message);
  24.        }
  25.    }
  26. }
  27. ?>


index.php
  1. <?php
  2. require_once ('newsletter-class.php');
  3. require_once ('mysql.php');
  4.  
  5. $topic = 'Test';
  6. $msg = 'Wiadomość testowa';
  7.  
  8. $sql = 'SELECT mail FROM emails';
  9.  
  10. $news = new Newsletter();
  11. $file = $news -> GetMailsFromFile('mail.txt', ';');
  12. $db = $news -> GetMailsFromDb($sql);
  13. // z pliku
  14. $news -> Send($file, $topic, $msg);
  15. //lub lub bazy
  16. $news -> Send($db, $topic, $msg);
  17. ?>
Go to the top of the page
+Quote Post
phpion
post
Post #2





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Ogólnie idziesz w dobrą stronę ale poczytaj o tym, co to jest polimorfizm i jak można go wykorzystać. Konkretnie chodzi mi o metody:
- GetMailsFromFile
- GetMailsFromDb
Generalnie nie powinno się tak robić (tworzyć osobnych metod do pobierania danych z różnych źródeł). Zdecydowanie lepiej utworzyć obiekt typu Loader, który by pobierał dane w speclajny sposób, coś na wzór:
  1. <?php
  2. abstract class Loader {
  3.    abstract public function load();
  4. }
  5.  
  6. class Loader_File extends Loader {
  7.    public function load() {
  8.        // wczytaj adresy z pliku
  9.    }
  10. }
  11.  
  12. class Loader_Database extends Loader {
  13.    public function load() {
  14.        // wczytaj adresy z bazy danych
  15.    }
  16. }
  17. ?>

Klasa Newsletter mogłaby wyglądać mniej-więcej tak:
  1. <?php
  2. class Newsletter {
  3.    private $loader;
  4.    
  5.    public function setLoader(Loader $loader) {
  6.        $this->loader = $loader;
  7.    }
  8.    
  9.    public function getMails() {
  10.        return $this->loader->load();
  11.    }
  12. }
  13. ?>

oraz wykorzystanie:
  1. <?php
  2. $obj = new Newsletter();
  3. $obj->setLoader(new Loader_File());
  4. print_r($obj->getMails());
  5. ?>
Go to the top of the page
+Quote Post
Cypherq
post
Post #3





Grupa: Zarejestrowani
Postów: 181
Pomógł: 9
Dołączył: 28.08.2006
Skąd: Katowice

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


Hmn... obsługa wyjątków, szczególnie przy pracy na pliku? Zawsze wydawało mi się, że nazewnictwo plików powinno wyglądać tak: class.Nazwaklasy.php, ale może to tylko moja konwencja (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)
Go to the top of the page
+Quote Post
piotrooo89
post
Post #4


Newsman


Grupa: Moderatorzy
Postów: 4 005
Pomógł: 548
Dołączył: 7.04.2008
Skąd: Trzebinia/Kraków




~phpion dzięki za przykład, uczę się dopiero i nie bardzo mi to wychodzi. zrobiłem coś takiego:

  1. <?php
  2. abstract class Loader
  3. {
  4.    abstract public function load();
  5. }
  6. class Loader_File extends Loader
  7. {
  8.    public function load()
  9.    {
  10.        $string = file_get_contents($file);
  11.        $mails_file = explode($separator, $string);
  12.        print_r($mails_file);
  13.    }
  14. }
  15. class Loader_Database extends Loader
  16. {
  17.    public function load()
  18.    {
  19.        $sql_query = mysql_query($sql);
  20.        while ($rows = mysql_fetch_row($sql_query))
  21.        {
  22.            $mails_db[] = $rows[0];
  23.        }
  24.        print_r($mails_db);
  25.    }
  26. }
  27. class Newsletter
  28. {
  29.    private $loader;
  30.  
  31.    public function setLoader(Loader $loader)
  32.    {
  33.        $this->loader = $loader;
  34.    }
  35.  
  36.    public function getMails()
  37.    {
  38.        return $this->loader->load();
  39.    }
  40. }
  41. ?>


ale jest źle. dlaczego? ponieważ nie wiem gdzie mam podać nazwę pliku/query do bazy.

~Cypherq
wiem o nazwach narazie testuje wszytko, później będę wyjątki łapał. narazie chce to uruchomić.

#EDIT

jak podam na sztywno nazwy pliku/query działa.

#EDIT2
zrobiłem tak, powiedzcie co o tym sądzicie:

newsletter-class.php
  1. <?php
  2. abstract class Loader
  3. {
  4.    abstract public function load();
  5. }
  6. class Loader_File extends Loader
  7. {
  8.    public function __construct($file, $separator)
  9.    {
  10.        $this->file = $file;
  11.        $this->sep = $separator;
  12.    }
  13.    public function load()
  14.    {
  15.        $string = file_get_contents($this->file);
  16.        $mails_file = explode($this->sep, $string);
  17.        return $mails_file;
  18.    }
  19. }
  20. class Loader_Database extends Loader
  21. {
  22.    public function __construct($sql)
  23.    {
  24.        $this->sql = $sql;
  25.    }
  26.    public function load()
  27.    {
  28.        $sql_query = mysql_query($this->sql);
  29.        while ($rows = mysql_fetch_row($sql_query))
  30.        {
  31.            $mails_db[] = $rows[0];
  32.        }
  33.        return $mails_db;
  34.    }
  35. }
  36. class Newsletter
  37. {
  38.    private $loader;
  39.  
  40.    public function setLoader(Loader $loader)
  41.    {
  42.        $this->loader = $loader;
  43.    }
  44.  
  45.    public function getMails()
  46.    {
  47.        return $this->loader->load();
  48.    }
  49.    public function Send($where, $subject, $message)
  50.   {
  51.       foreach($where as $mails)
  52.       {
  53.           mail($mails, $subject, $message);
  54.       }
  55.   }
  56. }
  57. ?>


index.php
  1. <?php
  2. require_once ('newsletter-class.php');
  3. require_once ('mysql.php');
  4.  
  5. $topic = 'Test';
  6. $msg = 'Wiadomość testowa';
  7.  
  8. $sql = 'SELECT mail FROM emails';
  9. $f = 'mail.txt';
  10.  
  11. $news = new Newsletter();
  12. $file = new Loader_File($f, ';');
  13. $db = new Loader_Database($sql);
  14.  
  15. $news -> setLoader($file);
  16.  
  17. print_r($news -> getMails());
  18.  
  19. $news -> Send($news->getMails(), $topic, $msg);
  20. ?>


Ten post edytował piotrooo89 10.04.2009, 20:03:48
Go to the top of the page
+Quote Post
erix
post
Post #5





Grupa: Moderatorzy
Postów: 15 467
Pomógł: 1451
Dołączył: 25.04.2005
Skąd: Szczebrzeszyn/Rzeszów




Wydzieliłem z http://forum.php.pl/index.php?showtopic=118120
Go to the top of the page
+Quote Post
piotrooo89
post
Post #6


Newsman


Grupa: Moderatorzy
Postów: 4 005
Pomógł: 548
Dołączył: 7.04.2008
Skąd: Trzebinia/Kraków




Cytat(erix @ 11.04.2009, 00:58:19 ) *


Dziękować.
Go to the top of the page
+Quote Post
netvalue
post
Post #7





Grupa: Zarejestrowani
Postów: 199
Pomógł: 2
Dołączył: 9.06.2008

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


hmm..
1. jak będę posiadał 60k maili w bazie czy pliku (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) ... To myślisz że wszystko gładko wyśle za jednym zamachem (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) ?
2. Może warto byłoby zaopatrzyć maila w nagłówki i autoryzację smtp. przy obecnym stanie większość serwerów oznaczy to flagą SPAM (IMG:http://forum.php.pl/style_emoticons/default/snitch.gif)
Go to the top of the page
+Quote Post
skowron-line
post
Post #8





Grupa: Zarejestrowani
Postów: 4 340
Pomógł: 542
Dołączył: 15.01.2006
Skąd: Olsztyn/Warszawa

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


@piotrooo89 a dlaczego wymyślasz koło od nowa jest klasa phpMailer ma wszystko czego tobie potrzeba.
Go to the top of the page
+Quote Post
phpion
post
Post #9





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Cytat(skowron-line @ 11.04.2009, 12:32:16 ) *
@piotrooo89 a dlaczego wymyślasz koło od nowa jest klasa phpMailer ma wszystko czego tobie potrzeba.

Może dlatego, że się chłopak uczy?
Go to the top of the page
+Quote Post
piotrooo89
post
Post #10


Newsman


Grupa: Moderatorzy
Postów: 4 005
Pomógł: 548
Dołączył: 7.04.2008
Skąd: Trzebinia/Kraków




Cytat(netvalue @ 11.04.2009, 11:16:33 ) *
1. jak będę posiadał 60k maili w bazie czy pliku (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) ... To myślisz że wszystko gładko wyśle za jednym zamachem (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) ?


tak tak już o tym pomyślałem. dodam odpowiednie funkcje.

Cytat(netvalue @ 11.04.2009, 11:16:33 ) *
2. Może warto byłoby zaopatrzyć maila w nagłówki i autoryzację smtp. przy obecnym stanie większość serwerów oznaczy to flagą SPAM (IMG:http://forum.php.pl/style_emoticons/default/snitch.gif)


nagłóweczki już są choć narazie chce zrobić ogólny zarys klasy i zapytać innych o zdanie.

Cytat(skowron-line @ 11.04.2009, 12:32:16 ) *
@piotrooo89 a dlaczego wymyślasz koło od nowa jest klasa phpMailer ma wszystko czego tobie potrzeba.


tak jak napisał ~phpion:

Cytat(phpion @ 11.04.2009, 12:42:36 ) *
Może dlatego, że się chłopak uczy?


i chyba bardziej cieszy coś własnego (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

a wracając do tematu jak oceniacie? co zmienić, dodać?

aktualnie wygląda to tak:

newsletter.Class.php
  1. <?php
  2. abstract class Loader
  3. {
  4.    abstract public function load();
  5.    public $errors =
  6.        array(
  7.        'no_file' => 'Plik nie istnieje',
  8.        'wrong_separator' => 'Nie podano separatora',
  9.        'wrong_sql' => 'Brak zapytania SQL',
  10.        'wrong_sql_col' => 'Podaj kolumne z adresami e-mail',
  11.        'wrong_sql_tab' => 'Podaj tabele SQL'
  12.        );
  13. }
  14. class Loader_File extends Loader
  15. {
  16.    public function __construct($file, $separator)
  17.    {
  18.        if (empty($separator))
  19.            throw new Exception($this->errors['wrong_separator']);
  20.  
  21.        $this->file = $file;
  22.        $this->sep = $separator;
  23.    }
  24.    public function load()    
  25.    {
  26.        if (!file_exists($this->file))
  27.            throw new Exception($this->errors['no_file']);
  28.            
  29.            $string = file_get_contents($this->file);
  30.            $mails_file = explode($this->sep, $string);
  31.            return $mails_file;
  32.    }
  33. }
  34. class Loader_Database extends Loader
  35. {
  36.    public function __construct($col, $tab)
  37.    {
  38.        if (empty($col) && empty($tab))
  39.            throw new Exception($this->errors['wrong_sql']);
  40.        elseif (empty($col))
  41.            throw new Exception($this->errors['wrong_sql_col']);
  42.        elseif (empty($tab))
  43.            throw new Exception($this->errors['wrong_sql_tab']);
  44.            
  45.        $this->col = $col;
  46.        $this->tab = $tab;
  47.    }
  48.    public function load()
  49.    {
  50.        $sql_query = mysql_query("SELECT `".$this->col."` FROM `".$this->tab."`");
  51.        while ($rows = mysql_fetch_row($sql_query))
  52.        {
  53.            $mails_db[] = $rows[0];
  54.        }
  55.        return $mails_db;
  56.    }
  57. }
  58. class Newsletter
  59. {
  60.    private $loader;
  61.  
  62.    public function setLoader(Loader $loader)
  63.    {
  64.        $this->loader = $loader;
  65.    }
  66.    public function getMails()
  67.    {
  68.        return $this->loader->load();
  69.    }
  70.    public function Send($where, $subject, $message, $head)
  71.    {
  72.        foreach($where as $mails)
  73.        {
  74.            mail($mails, $subject, $message, $head);
  75.        }
  76.    }
  77. }
  78. ?>


index.php
  1. <?php
  2. require_once ('newsletter.Class.php');
  3. require_once ('mysql.php');
  4.  
  5. $topic = 'Test';
  6. $msg = 'Wiadomość testowa';
  7. $headers .= "From: Olaszewski <piotroo89@gmail.com>r\n";
  8. $headers .= "Reply-To: Olaszewski <piotroo89@gmail.com>r\n";
  9. $headers .= "Return-Path: Olaszewski <piotroo89@gmail.com>r\n";
  10. $headers .= 'X-Mailer: PHP/' . phpversion() ."r\n";
  11. $headers .= 'MIME-Version: 1.0'. "\n";
  12. $headers .= 'Content-type: text/html; charset=utf-8' . "r\n";
  13. $headers .= "Content-transfer-encoding: utf-8r\n";
  14.  
  15. $column_sql = 'mail';
  16. $table_sql = 'emails';
  17.  
  18. $f = 'mail.txt';
  19.  
  20. try
  21. {
  22.    $news = new Newsletter();
  23.    $file = new Loader_File($f, ';');
  24.    $db = new Loader_Database($column_sql, $table_sql);
  25.    $news -> setLoader($db);
  26.  
  27.    print_r($news->getMails());
  28.  
  29.    $news -> Send($news->getMails(), $topic, $msg, $headers);
  30. }
  31. catch(Exception $e)
  32. {
  33.    $error = ($e->getMessage());
  34.    echo $error;
  35. }
  36. ?>
Go to the top of the page
+Quote Post
phpion
post
Post #11





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Moje 2 uwagi:

1. Loader::$errors - wg mnie komunikaty błędów powinny znajdować się w wyspecjalizowanych klasach, ponieważ teraz każda klasa pochodna będzie miała wszystkie komunikaty (po co np. w Loader_File komunikat wrong_sql?). Ponadto rozważyłbym zapis komunikatów w postaci stałych wewnątrz klasy (const).

2. Nie podoba mi się sposób dodawania nagłówków. Zrobiłbym to raczej w ten sposób:
  1. <?php
  2. class Newsletter {
  3.    private $headers = array();
  4.  
  5.    //...
  6.  
  7.    public function addHeader($name, $value) {
  8.        $this->headers[$name] = $value;
  9.    }
  10. }
  11. ?>

i potem przy wysyłaniu maila wystarczyłoby przekształcić tą tablicę na stringa (tak, jak to robisz w przykładzie). Dzięki temu rozwiązaniu możesz już w konstruktorze machnąć kilka domyślnych nagłówków (np. ustawić kodowanie oraz typ wysyłanego maila).
Go to the top of the page
+Quote Post
piotrooo89
post
Post #12


Newsman


Grupa: Moderatorzy
Postów: 4 005
Pomógł: 548
Dołączył: 7.04.2008
Skąd: Trzebinia/Kraków




dzięki za kolejne rady. obecnie klasa wygląda tak:

newsletter.Class.php
  1. <?php
  2. abstract class Loader
  3. {
  4.    abstract public function load();
  5. }
  6. class Loader_File extends Loader
  7. {
  8.    const WRONG_FILE = 'Plik nie istnieje';
  9.    const WRONG_SEPARATOR = 'Nie podano separatora';
  10.    
  11.    public function __construct($file, $separator)
  12.    {
  13.        if (empty($separator))
  14.            throw new Exception(Loader_File::WRONG_SEPARATOR);
  15.  
  16.        $this->file = $file;
  17.        $this->sep = $separator;
  18.    }
  19.    public function load()    
  20.    {
  21.        if (!file_exists($this->file))
  22.            throw new Exception(Loader_File::WRONG_FILE);
  23.            
  24.            $string = file_get_contents($this->file);
  25.            $mails_file = explode($this->sep, $string);
  26.            return $mails_file;
  27.    }
  28. }
  29. class Loader_Database extends Loader
  30. {
  31.    const WRONG_SQL = 'Brak zapytania SQL';
  32.    const WRONG_SQL_COL = 'Podaj kolumne z adresami e-mail';
  33.    const WRONF_SQL_TAB = 'Podaj tabele SQL';
  34.    
  35.    public function __construct($col, $tab)
  36.    {
  37.        if (empty($col) && empty($tab))
  38.            throw new Exception(Loader_Database::WRONG_SQL);
  39.        elseif (empty($col))
  40.            throw new Exception(Loader_Database::WRONG_SQL_COL);
  41.        elseif (empty($tab))
  42.            throw new Exception(Loader_Database::WRONF_SQL_TAB);
  43.            
  44.        $this->col = $col;
  45.        $this->tab = $tab;
  46.    }
  47.    public function load()
  48.    {
  49.        $sql_query = mysql_query("SELECT `".$this->col."` FROM `".$this->tab."`");
  50.        while ($rows = mysql_fetch_row($sql_query))
  51.        {
  52.            $mails_db[] = $rows[0];
  53.        }
  54.        return $mails_db;
  55.    }
  56. }
  57. class Newsletter
  58. {
  59.    private $loader;
  60.    private $headers = array();
  61.  
  62.    public function setLoader(Loader $loader)
  63.    {
  64.        $this->loader = $loader;
  65.    }
  66.    public function getMails()
  67.    {
  68.        return $this->loader->load();
  69.    }
  70.    public function addHeaders($value)
  71.    {
  72.        $this->headers[] = $value;
  73.    }
  74.    public function getHeaders()
  75.    {
  76.        foreach($this->headers as $heads)
  77.        {
  78.            $show_heads .= $heads;
  79.        }
  80.        return $show_heads;
  81.    }
  82.    public function Send($where, $subject, $message, $head)
  83.    {
  84.        foreach($where as $mails)
  85.        {
  86.            mail($mails, $subject, $message, $head);
  87.        }
  88.    }
  89. }
  90. ?>


index.php
  1. <?php
  2. require_once ('newsletter.Class.php');
  3. require_once ('mysql.php');
  4.  
  5. $topic = 'Test';
  6. $msg = 'Wiadomość testowa';
  7. /*************
  8. $headers .= "From: Olaszewski <piotroo89@gmail.com>r\n";
  9. $headers .= "Reply-To: Olaszewski <piotroo89@gmail.com>r\n";
  10. $headers .= "Return-Path: Olaszewski <piotroo89@gmail.com>r\n";
  11. $headers .= 'X-Mailer: PHP/' . phpversion() ."r\n";
  12. $headers .= 'MIME-Version: 1.0'. "\n";
  13. $headers .= 'Content-type: text/html; charset=utf-8' . "r\n";
  14. $headers .= "Content-transfer-encoding: utf-8r\n";
  15. *************/
  16.  
  17. $column_sql = 'mail';
  18. $table_sql = 'emails';
  19.  
  20. $f = 'mail.txt';
  21.  
  22. try
  23. {
  24.    $news = new Newsletter();
  25.    $file = new Loader_File($f, ';');
  26.    $db = new Loader_Database($column_sql, $table_sql);
  27.    
  28.    $news->setLoader($file);
  29.    
  30.    $news->addHeaders("From: Olaszewski <piotroo89@gmail.com>r\n");
  31.    $news->addHeaders("Reply-To: Olaszewski <piotroo89@gmail.com>r\n");
  32.    $news->addHeaders("Content-type: text/html; charset=utf-8r\n");
  33.  
  34.    $news -> Send($news->getMails(), $topic, $msg, $news->getHeaders());
  35. }
  36. catch(Exception $e)
  37. {
  38.    $error = ($e->getMessage());
  39.    echo $error;
  40. }
  41. ?>


czekam na dalsze rady (optymalizacja, poprawienie działania etc.).
Go to the top of the page
+Quote Post
bim2
post
Post #13





Grupa: Zarejestrowani
Postów: 1 873
Pomógł: 152
Dołączył: 9.04.2006
Skąd: Berlin

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


Może
  1. <?php
  2. $news->addHeaders('Content-type', 'text/html; charset=utf-8');
  3. ?>

a \r\n dodawać automatycznie ? (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
skowron-line
post
Post #14





Grupa: Zarejestrowani
Postów: 4 340
Pomógł: 542
Dołączył: 15.01.2006
Skąd: Olsztyn/Warszawa

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


Według mnie mógłbyś dać więcej metod typu
Kod
setMessage( $msg )
{
$this->msg = stripslashes( $msg );
}
addAddress( $address )
{
//walidacja adresu
}

Albo jeszcze sprawdzać czy wiadomość nie jest pusta.

  1. <?php
  2. public function addHeaders($value)
  3.   {
  4.       $this->headers[] = $value;
  5.   }
  6. public function Send($where, $subject, $message)
  7.   {
  8.       foreach($where as $mails)
  9.       {
  10.           mail($mails, $subject, $message, $his->headers);
  11.       }
  12.   }
  13. ?>

Po co wstawiasz do metody kolejny parametr jak możesz je wyciągać wewnątrz klasy.
Tak samo jak message i where i subject i miałbyś
  1. <?php
  2. $news->send();
  3. ?>
Go to the top of the page
+Quote Post
Cypherq
post
Post #15





Grupa: Zarejestrowani
Postów: 181
Pomógł: 9
Dołączył: 28.08.2006
Skąd: Katowice

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


Te komunikaty o błędach, zawsze myślałem, że wygodniej trzymać w osobnym pliku. Wtedy zmieniając język komunikatów nie grzebiemy w klasie, a chyba o to chodzi?
Go to the top of the page
+Quote Post

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: 24.09.2025 - 07:25