Итак, благодаря azzzi и его уроку http://flapps.ru/forum/topic1317.html, а также Александру с http://flapps.ru/forum/topic2052-20.html был переписан последний урок с использованием первого, на основе JQuery.
Причина:
Первый урок от azzzi простой и полностью подходит, однако его исходник не позволяет зациклить по 100, также нет формы для ввода текста уведомления, а значит всё это придется дополнять.
Второй урок от Александра я так и не смог оценить. Дело в том, что в отличие от желаемого отображения пошаговой отправки я получил зависание скрипта (при попытке отправить 40 000 пользователям). Но, как говорит Александр, он работает. Однако, не знаю, поэтому написал еще и свой урок.
Мой урок - это банальное соединение двух уроков в один с пошаговым отображением хода отправки + несколько приятных мелочей.
Возможности скрипта:
1. Отправка, хоть до 100 000 и более пользователей.
2. Есть форма для ввода текста уведомления.
3. Есть возможность в любой момент остановить рассылку уведомлений.
4. Есть возможность указать позицию, с которой нужно начать рассылать (по умолчанию - 0, это первый пользователь в базе).
5. Введется лог рассылки с указанием минут и секунд
6. Очистка лога рассылки
7. Автоматическая рассылка (указали текст, нажали "Отправить" и ушли пить чай. Отправка 40 000 пользователям заняла у меня около 25 минут)
8. Минимальная нагрузка на сервер (в моём случае, нагрузки вообще никакой не оказалось)
9. Подсчет общего количества пользователей в базе
Требования для скрипта:
1. База пользователей должна быть в MySQL.
2. Поддержка CURL на хостинге.
3. Ссылка на библиотеку JQuery (уже добавлена в скрипт)
Поехали:
1. Файл "config.php" - изменять название НЕЛЬЗЯ.
Код: Выделить всё
<?php$dbhost = "localhost"; // Хостинг$dbname = "base_TEST"; // Название базы данных MySQL$dbuser = "user_TEST"; // Имя пользователя базы данных MySQL$dbpass = "pass_TEST"; // Пароль к базе данных MySQL $dbtable = "table_TEST"; // Название таблицы базы пользователей ВКонтакте$idcolumn = "ID"; // Название колонки с пользовательскими ID $api_id="1234567890"; // ID приложения$api_key="QWERTYUIOPASDFGHJKLZXCVBNM"; // Защищенный ключ // Набор PHP функций (НЕ ИЗМЕНЯТЬ!)function db_connect($dbhost, $dbuser, $dbpass, $dbname){mysql_connect($dbhost, $dbuser, $dbpass)or die('Невозможно подключиться к базе данных: ' . mysql_error());mysql_select_db($dbname); } function do_query($query){ global $res; $res = mysql_query($query) or die("Неверный запрос: " . mysql_error());}?>
В данном файле есть всё необходимое, чтобы настроить скрипт уведомления под Ваше приложение и Ваш хостинг.
Во-первых, меняем данные для подключения к базе MySQL (название базы, пользователь, пароль и т.п.).
Во-вторых, самое главное это указать название колонки с ID пользователей (в других уроках это было "uid", у меня просто "ID"), а также название таблицы (у меня это "table_TEST").
В-третьих, указываем app_id и защищенный ключ.
2. Файл "z_sender.php" - изменять название НЕЛЬЗЯ.
Код: Выделить всё
<?include_once("config.php"); if ($_POST) {$first = $_POST['fromid'];$tbname = $_POST['fromtb']; if (trim($first) == '') {$first = "0";}$userids = "";$symbol = ""; db_connect($dbhost, $dbuser, $dbpass, $dbname);mysql_query("SET NAMES 'cp1251'");$result = mysql_query("SELECT * FROM $tbname LIMIT $first, 100");while ($row = mysql_fetch_array($result)) {if ($userids !== "") {$symbol = ",";} $userids = $userids.$symbol.$row[$idcolumn];} $mesage= $_POST['yourtext']; $rand = rand();$timestamp = time()+300; $sig = md5("api_id=".$api_id."message=".$mesage."method=secure.sendNotificationrandom=".$rand."timestamp=".$timestamp."uids=".$userids."v=2.0".$api_key);$postvars="api_id=".$api_id."&message=".$mesage."&method=secure.sendNotification&random=".$rand."×tamp=".$timestamp."&uids=".$userids."&v=2.0&sig=".$sig; $chp = curl_init('http://api.vkontakte.ru/api.php');curl_setopt($chp, CURLOPT_HEADER,0);curl_setopt($chp, CURLOPT_RETURNTRANSFER ,1);curl_setopt($chp, CURLOPT_POST, 1);curl_setopt($chp, CURLOPT_POSTFIELDS, $postvars);$res = curl_exec($chp);curl_close($chp); $datetime = date("[H:i:s] ");$len = strlen($res);if ($len !== 51) {$check = strpos($res, 'Invalid');if ($check == false) {echo "$datetime Отправились уведомления до: $res";} else {echo "$datetime В данной позиции ID не найдены.";}} else{echo "$datetime Ни одного уведомления не доставлено.";}} else echo "ERROR.";?>
Собственно главный обработчик, который принимает с помощью AJAX запроса (методом POST) позицию ID (с которого начинается рассылка), а также текст уведомления. Есть защита от прямого обращения к файлу. Никаких изменений вносить в этот файл не нужно (если только поменять тексты ответов после команды "echo"). Далее происходит рассылка (за раз не больше 100 пользователям, по правилам ВКонтакте). Успешный\не успешный ответ передаёт обратно следующему файлу.
3. Файлу "sendnotify.php" - Вы можете изменить название файла на любое другое. Рекомендуется это сделать сразу, чтобы никто кроме Вас не смог разослать уведомления Вашим пользователям.
Код: Выделить всё
<?phpinclude_once("config.php");db_connect($dbhost, $dbuser, $dbpass, $dbname);mysql_query("SET NAMES 'cp1251'");$result = mysql_query("SELECT * FROM $dbtable");$all = (mysql_num_rows($result)) - 100;?> <html><head><meta http-equiv="Content-Type" content="text/html; charset=windows-1251" /><title>Отправка уведомлений</title><script src="http://code.jquery.com/jquery.min.js" type="text/javascript"></script></head><body> <script type="text/javascript">function ClearLog() {document.getElementById('z_status').innerHTML = "<br /><br /><B>Лог процесса рассылки очищен!</B>";} function SendMsg() {var sOldText = document.getElementById('z_status').innerHTML;var sSendText = document.getElementById('z_sendtext').value;var sPosition = document.getElementById('z_position').value;var sFinish = parseInt("<? echo $all;?>");var sCurrent = parseInt(sPosition); if (sSendText == '') { document.getElementById('z_status').innerHTML = sOldText+ "<br /><br /><B>Пожалуйста, введите текст уведомления!</B>";} else { if(document.getElementById('s_box').checked) { if (sFinish < sCurrent) {document.getElementById('z_status').innerHTML = sOldText+ "<br /><br /><B>Отправка уведомлений завершена, либо превышен диапазон ID.</B>"+'<span id="s_finish"></span>';document.getElementById('s_finish').scrollIntoView(); } else {document.getElementById('z_status').innerHTML = sOldText+ "<br /><br />Отправка уведомлений от позиции <b>" + sPosition + "</b> из <b><? echo $all;?></b> ..."; $.post("/z_sender.php",{fromid: sPosition, fromtb: '<? echo $dbtable;?>', yourtext: sSendText},onAjaxSuccess);} } else {document.getElementById('z_status').innerHTML = sOldText+ "<br /><br /><B>Отправка уведомлений приостановлена, либо не включена!</B>"+'<span id="s_finish"></span>';document.getElementById('s_finish').scrollIntoView();}}} function onAjaxSuccess(data){var sOldText = document.getElementById('z_status').innerHTML;var sPosition = parseInt(document.getElementById('z_position').value) + 100;document.getElementById('z_position').value = sPosition;document.getElementById('z_status').innerHTML = sOldText + "<br />" + data + '<span id="yak' + sPosition + '"></span>';document.getElementById('yak'+sPosition).scrollIntoView(); SendMsg();} </script> <h1>Отправка уведомлений</h1>Начать отправку с позиции (от 0 до <?=$all?>):<br /><input type="text" id="z_position" style="width:100px;" value="0"><input type="checkbox" id="s_box" checked> Включить\выключить отправку<br />Текст уведомления (максимум 1024 символа):<br /><textarea id="z_sendtext" cols="50" rows="5"></textarea><br /><br /><input type="button" value="Отправить" onClick="SendMsg()"> <input type="button" value="Очистить" onClick="ClearLog()"><br /><div style="margin-top: 6px; border: 0px solid #E0E0E0; width: 800px; height: 250px; overflow: auto;"><span id="z_status"></span></div></body></html>
Это Файл-форма для ввода текста уведомления. Вводим свой текст, ставим галочку "Включить\выключить отправку" (по умолчанию, поставлена). Выбираем позицию (по умолчанию, 0, значит рассылка будет начинаться от 1 пользователя в базе). Ниже наблюдаем лог рассылки.
В любой момент Вы можете убрать галочку "Включить\выключить отправку" и процесс рассылки остановится, а позиция сохранится.
Вот и всё! А вот результат:
Пару слов от себя:
Скрипт сделан на совесть. Не так, чтобы полностью идеален. Переписывая уроки, возможно в коде остались лишние (не нужные строчки). Также добавил пару защит на пустой текст уведомления, и не существование позиций ID в базе.
Пару рекомендаций по работе со скриптом:
1. В процессе рассылки, время от времени, делайте остановку (снимая галочку).
Потому что, если у Вас большое количество пользователей, а хостинг слабый, то в таком случае есть вероятность, что сайт не выдержит наплыв пользователей.
2. В процессе рассылки, время от времени, делайте очистку лога
Если у Вас большое количество пользователей, то размер лога может увеличиваться до 1 и более МБ. Как результат - увеличение нагрузки на сервер.