Рассылка писем через крон

Тема в разделе "PHP", создана пользователем euheni, 28 окт 2009.

Статус темы:
Закрыта.
Модераторы: latteo
  1. euheni

    euheni Постоялец

    Регистр.:
    6 сен 2007
    Сообщения:
    118
    Симпатии:
    21
    Нужно сделать рассылку на ящики клиентов, которые лежат в базе.

    Для сего написал небольшой скрипт:

    PHP:
    <?php

    if (isset($_POST['title']) && isset($_POST['mess']))
    {

        require_once 
    "cfg/connect.inc.php";
        require_once 
    "cfg/DB.php";
        
        
    $db = new Database();
        
        
    $sql "SELECT distinct(cust_email) FROM SS_orders";
        
        
    $result $db -> query($sql);
        if (
    $db -> get_nom($result)) 
        {
            
    $mails = array();
            while (
    $row $db -> assoc($result)) 
            {
                
    $mails[] = $db -> from_db($row);
            }
        }
        
        
    $from  'От кого <info@mysite.com>';
        
         foreach (
    $mails as $m)
        {
            if(
    preg_match("/[0-9a-z_]+@[0-9a-z_^\.]+\.[a-z]{2,4}/i"$m[cust_email])) 
            {    
                
    $to $m[cust_email];
                
    $title $_POST['title'];
                
    $mess $db -> from_db($_POST['mess']);
                
                
    $headers "Content-type: text/plain; charset=windows-1251" "\r\nFrom: ".$from"\r\n";
                
                
    mail($to$title$mess$headers);
                
             }
        }
        
        echo 
    "<div align=center><b>Готово</b></div>";
        
        
    $smarty->assign("mailer"$mailer);
        
    }
    ?>
    Спросил у хостера будет ли работать такой скрипт, он ответил, что на рассылку стоит ограничение 200 писем в час.
    Я добавил в цикл
    PHP:
    sleep(20);
    чтобы получилось 180 писем в час.

    Но таким образом скрипту нужно будет выполняться 10 часов.
    На это хостер ответил: "На виртуальном хостинге резидентные пользовательские программы не разрешаются. Просто запускайте определенную часть по крону каждый час."

    Помогите догнать как это реализовать.
     
  2. Darkmind

    Darkmind SNMP maniac

    Регистр.:
    31 май 2006
    Сообщения:
    183
    Симпатии:
    76
    В панели управления надо найти доступ к крону (планировщику) и добавить туда абсолютный путь к файлу. Ну и не забываем про set_time_limit(0), иначе через 30 секунд скрипт отвалится.
     
  3. euheni

    euheni Постоялец

    Регистр.:
    6 сен 2007
    Сообщения:
    118
    Симпатии:
    21
    На сколько я понял, нужно N раз запусить скрипт через Cron.
    Причем каждый раз должны браться разные куски из базы.

    Просто запускать через час наверно не покатит.
     
  4. Darkmind

    Darkmind SNMP maniac

    Регистр.:
    31 май 2006
    Сообщения:
    183
    Симпатии:
    76
    Тогда надо немного переделать идею скрипта - он должен не только рассылать письма, но и помечать адреса, по которым он уже отослал их. И при последующем запуске, по уже пройденным адресам письма не посылать.

    А нет желания поставить простенький
    http://gregory.kokanosky.free.fr/v4/phpmynewsletter/
    И разделив базу на несколько частей рассылать через него?

    Хотя, если речь идёт о постоянной рассылке, тогда проще написать решение самому.
     
  5. Shurikus84

    Shurikus84 Создатель

    Регистр.:
    21 апр 2009
    Сообщения:
    11
    Симпатии:
    0
    Лучше хранить по каждому письму время отправки в базе и так контролировать лимит 200 писем в час, а не шаманить с sleep()
     
  6. t0wer

    t0wer BlackHerald

    Регистр.:
    24 июн 2008
    Сообщения:
    733
    Симпатии:
    422
    1) в вашем скрипте ставим цикл на 180 писем ( или 200, как хотите)
    2) в кроне прописываем чтобы запускал каждый час скрипт... вот и все


    Пример: запускать каждый час ежедневно
    Код:
    0 */1 * * * /home/httpd/vhosts/domain.tld/httpdocs/scripts/script.php
    абсолютный путь до вашего скрипта (/home/httpd/vhosts/domain.tld/httpdocs/scripts/script.php) ставим свой!!!

    Значения первых пяти полей:
    1. минуты — число от 0 до 59
    2. часы — число от 0 до 23
    3. день месяца — число от 1 до 31
    4. номер месяца в году — число от 1 до 12
    5. день недели — число от 0 до 7 (0-Вс,1-Пн,2-Вт,3-Ср,4-Чт,5-Пт,6-Сб,7-Вс)

    ----------------------------
    Поскольку не все PHP-программы могут работать без предварительной модификации, можно запускать их через wget.
    Например:

    Код:
    /usr/bin/wget -O /dev/null -q http://mydomain.mchost.ru/cron.php?action=123
    Если в скрипте используются функции require, include, причём в них указаны относительные пути, то в начале выполняемого скрипта используйте вызов функции chdir(), которая задаст текущую рабочую директорию.
     
  7. euheni

    euheni Постоялец

    Регистр.:
    6 сен 2007
    Сообщения:
    118
    Симпатии:
    21
    Подскажите плиз как мне каждый раз при запуске скрипта выбирать по 200 мыл чтобы они не повторялись.

    Сейчас у меня все выбирается в один массив вот так:

    PHP:
        $sql "SELECT distinct(cust_email) FROM SS_orders";
        
        
    $result $db -> query($sql);
        if (
    $db -> get_nom($result)) 
        {
            
    $mails = array();
            while (
    $row $db -> assoc($result)) 
            {
                
    $mails[] = $db -> from_db($row);
            }
        } 
    И еще ... текст который рассылается ... я делал его через форму постом, а через крон если запуск ставить, то я так понимаю уже никак так не сделать. Сначала надо будет его записать куда-то (в базу например) а потом уже оттуда брать?
     
  8. tostrss

    tostrss

    Регистр.:
    16 окт 2007
    Сообщения:
    771
    Симпатии:
    217
    Рандом в базе вещь очень извращенческая.
    Лучше выбрать все базы 1 запросом, записать их в массив и применить функцию
    array_rand
    например так
    PHP:
    $array array_rand($emails200);
    Из массива мыл, возьмется рандомно 200 мыльников (без повторений)
    потом делаем так
    PHP:
    foreach ($emails as $value) {
        
    $email $emails[$value];
    }

    Ды лучше в файл записывать, зачем лишний раз нагружать базу.
     
  9. euheni

    euheni Постоялец

    Регистр.:
    6 сен 2007
    Сообщения:
    118
    Симпатии:
    21
    Мне надо на все мыльники отправить. Их около 1800.
    На сколько я понял
    PHP:
    $array array_rand($emails200);
    при 2-й выборке через час выберет рандомно 200 мыл, но в них могут попасть и те, что выбирались в 1-й раз.
    А повторы не нужны.
     
  10. tostrss

    tostrss

    Регистр.:
    16 окт 2007
    Сообщения:
    771
    Симпатии:
    217
    PHP:
    $array array_rand($emails200); 
    PHP:
    foreach ($array as $value) { 
        
    $email $emails[$value]; 
        unset(
    $emails[$value]);
    unset удалит уже взятый элемент из массива $emails

    при следующем вызове array_rand в массиве $emails будут отсутсвовать ранее использованные мыльники.

    Это что касается 1 запуска ,т.е. в нем все эти циклы будут.

    Если нужно чтобы скрипт брал эти значения при каждом своем запуске, тогда нужно писать мыла или в файл (и каждый раз удалять из файла) или маркировать их в базе.
    Например сделал апдейт, поставил лимит 200, записям присвоил флаг
    status = 1 ( 0 - не использованы, 1 - спамятся в данный момент, 2 - проспамлены)

    Затем выбрал эти мыльники, отослал, снял метку то что они в данный момент отсылаются, поставил статус = 2 и т.д.
     
Статус темы:
Закрыта.