|
|
|
| На почтовый ящик приходит письмо, значения кот. необходимо занести в базу данных в соотв-ие таблицы и поля.
Например, на ящик 12345@primer.ru пришло письмо с полями:
3258
Иванов И.В.
АСОИ
3
8,6
На веб страничке есть кнопка при нажатии на кот. эти данные должны попасть в базу данных "mgtu" в таблицу student c полями : N, fio, fakultet, kurs, sr_ball
Подскажите можно ли это как-то сделать.... | |
|
|
|
|
|
|
|
для: Lilu
(06.02.2007 в 10:21)
| | Вообще - можно практически все =) но по конкретике - не буду прям приводить код, т.к. с ходу не напишу за минуту - дам общую концепцию...
Смотри в сторону темы - работа с сокетами + протокол POP3 - это тебе поможет забирать почту с любого почтового сервака, даже если он не на том-же хостинге.
Далее в сторону функций для работы с используемой БД + Transact SQL - это для внесения данных в БД.
Ну и соответственно - см. выше, удаляешь письмо, данные из которого забраны, чтобы не внести их повторно.
Вот вкратце алгоритм работы. | |
|
|
|
|
|
|
|
для: ZuArt
(06.02.2007 в 10:26)
| | ЗЫ. В дополнение можно расширить функционал - если данные в письме не в нужном формате или нехватка данных - автоматизировать обработку или "ответное" письмо с текстом аля "некоректные данные" или просто считать письмо неформатом и пропустить... | |
|
|
|
|
|
|
|
для: Lilu
(06.02.2007 в 10:21)
| | Как почтовый ящик связан с веб-страничкой?
Или это самое письмо и является веб-страницей? | |
|
|
|
|
|
|
|
для: Trianon
(06.02.2007 в 10:47)
| | [поправлено модератором] | |
|
|
|
|
|
|
|
для: ZuArt
(06.02.2007 в 11:01)
| | Я ничего не утверждал. Я задал два вопроса, и оба - не в Ваш адрес.
[поправлено модератором] | |
|
|
|
|
|
|
|
для: Trianon
(06.02.2007 в 11:06)
| | [поправлено модератором] | |
|
|
|
|
|
|
|
для: Trianon
(06.02.2007 в 11:06)
| | Дело в том, что у меня есть программа служебная она емеет веб интерфейс и на ней есть кнопка "загрузить почту", при нажатии должна заполниться база, после успешной загрузки, например, появится надпись "обновление базы произошло успешно" и далее можно с этой же программы, открывая другой интерфейс пользоваться загруженными новыми данными....
Вот так...
Сокеты - для меня это совсем не знакомая степь, вот читаю, пытаюсь разобраться......
P.S. Я аж испугалась, чуть ли конфликт не возник на моей теме, вот это спросила :)))) | |
|
|
|
|
|
|
|
для: lilu
(06.02.2007 в 11:27)
| | Протокол POP3 - это диалоговый протокол - на каждую команду приходит ответ, так что блок - посылка - прием ответа можно вычленить в отделюную функцию. Пишу очень грубо - стопудово не заработает сразу - там надо протокол POP3 - который я с ходу не помню =( - ну и свои коррективы внести - тут общая концепция.
<?
function ToSend($fl, $txt)
{
$ret = "";
fwrite($fp, $txt);
while (!feof($fp))
{
$ret .= fgets($fp, 128);
};
return $ret;
};
$fp = fsockopen("mail.primer.ru", 110, $errno, $errstr, 30);
if (!$fp)
{
echo "Ошибка подключения к почтовому серверу $errstr ($errno)<br />\n";
return;
};
$ret = ToSend($fp,"команда для подключения");
$ret = ToSend($fp,"команда для логина");
$ret = ToSend($fp,"команда для пасс");
$ret = ToSend($fp,"запрос почты");
далее как-то в цикле или по условному оператору - запрос, обработка и удаление писем...
$ret = ToSend($fp,"закрытие ящика");
fclose($fp);
echo "Почта обработана";
}
?>
|
| |
|
|
|
|
|
|
|
для: lilu
(06.02.2007 в 11:27)
| | >Дело в том, что у меня есть программа служебная она емеет веб интерфейс и на ней есть кнопка "загрузить почту", при нажатии должна заполниться база, после успешной загрузки, например, появится надпись "обновление базы произошло успешно" и далее можно с этой же программы, открывая другой интерфейс пользоваться загруженными новыми данными....
То есть, адрес, на который приходят эти письма - это некоторый служебный адрес этой системы, а не чей-то персональный?
И по нажатию кнопки скрипт должен пересмотреть письма в почтовом ящике, прочитать нужные, и переложить данные из них в таблицу БД?
>Вот так...
>Сокеты - для меня это совсем не знакомая степь, вот читаю, пытаюсь разобраться......
Придется работать с почтовым сервером по протоколу POP3. Для этого можно применить либо сокеты, либо php-расширение imap.
>P.S. Я аж испугалась, чуть ли конфликт не возник на моей теме, вот это спросила :))))
Не обращайте внимания, уж Вы-то явно повода не давали. :) | |
|
|
|
|
|
|
|
для: Trianon
(06.02.2007 в 12:03)
| | >То есть, адрес, на который приходят эти письма - это некоторый служебный адрес этой системы, а не чей-то персональный?
Ящик специально для этого созданный, личных писем нет там.
>И по нажатию кнопки скрипт должен пересмотреть письма в почтовом ящике, прочитать нужные, и переложить данные из них в таблицу БД?
Отфильтровывать данные не нужно, туда приходят только нужные и в таком виде, кот. представлен выше...Причём на каждого студента - отдельное письмо...
>Придется работать с почтовым сервером по протоколу POP3. Для этого можно применить либо сокеты, либо php-расширение imap.
что первый вариант, что второй - :( без примеров - Никак | |
|
|
|
|
|
|
|
для: lilu
(06.02.2007 в 12:19)
| | Хммм... как уже указал выше, пример более чем кустарный, но от него можно оттолкнуться в нужную сторону + ОБЯЗАТЕЛЬНО протокол POP3 - без него никак...
ну или как уже выше указывалось - воспользоваться более продвинутыми модулями - там наверняка все проще ;) | |
|
|
|
|
|
|
|
для: lilu
(06.02.2007 в 12:19)
| | Вот пример.
Особое внимание обратите на то, что у сервера бывают запросы с однострочными ответами, и бывают с многострочными.
<?
define('DEBUG', true); // debug mode
define('SMTP_TIMEOUT', 10); // in seconds
function send($fs, $data ='')
{
if($data !== 0)
{
if(constant('DEBUG'))
echo 'send: '.$data. "<br>\r\n";
fwrite($fs, $data."\r\n");
}
}
function send_rcv($fs, $data ='', $list=false)
{
send($fs, $data);
if(feof($fs))
return false;
$n = fgets($fs);
if(constant('DEBUG'))
echo 'recv: '.$n. "<br>\r\n";
if($n === false) return $n;
if($n[0] !== '+') return '2 '.$n;
if($list === false) return '1 '.$n;
$r = array($n);
while(($n = fgets($fs)) !== false && !($n[0] == '.'&& $n[1] != '.'))
{
if(constant('DEBUG'))
echo 'recv: '.$n. "<br>\r\n";
if($n[0]=='.' && $n[1]=='.') $n = substr($n, 1);
$r[] = $n;
}
return $r;
}
function pop3_mail(
$server_host
= "pop3.primer.ru" // адрес сервера pop3
, $login
='12345' // имя пользователя почтового ящика
, $password
='password' // пароль почтового ящика
)
{
$fs = fsockopen($server_host, 110, $errno, $errstr, constant('SMTP_TIMEOUT'));
if(!$fs)
{
echo "Cannot connect to $server_host: [$errno] $errstr";
return 0;
}
if(1 != intval(($s = send_rcv($fs,0)))) die("Status: $s");
if(1 != intval(($s = send_rcv($fs,$c="USER $login")))) die("Status $c: $s");
if(1 != intval(($s = send_rcv($fs,$c="PASS $password")))) die("Status $c: $s");
$s = send_rcv($fs,$c="LIST", 1);
if(!is_array($s)) die("Status $c : $s");
print_r($s);
$s = send_rcv($fs,$c="UIDL", 1);
if(!is_array($s)) die("Status $c : $s");
print_r($s);
$s = send_rcv($fs,$c="TOP 1 1", 1);
if(!is_array($s)) die("Status $c : $s");
print_r($s);
}
pop3_mail();
?>
|
Описание протокола POP3 можно поглядеть здесь | |
|
|
|
|
|
|
|
для: Trianon
(06.02.2007 в 12:24)
| | Спасибо за пример, но без вашей помощи разобраться сложновато.....
Можете хоть кратко пояснить что тут делается, для того кто с этим сталкивается впервые - непросто понять это... | |
|
|
|
|
|
|
|
для: lilu
(06.02.2007 в 13:13)
| | Сейчас написать прямо скрипт не смогу - дела, но чуток попозжее (ближе к вечеру или утром), если будет актуально - кину... | |
|
|
|
|
|
|
|
для: ZuArt
(06.02.2007 в 13:57)
| | Буду оч признательна, а пока буду с примером разбираться.... | |
|
|
|
|
|
|
|
для: lilu
(06.02.2007 в 14:07)
| | Не претендую на супер-код - написано практически "набело" на скорую руку - тестил не сильно...
<?php
class wspPop3
{
var $fs;
var $twt;
var $Error;
function wspPop3()
{
$this->twt = 5;
$this->fs = false;
$this->Error = '';
}
// читать из потока
function Read(&$buff, $lst=false, $lim=4096)
{
$this->Error = 'Не открыт ящик';
if (!$this->fs)
return false;
$this->Error = 'Нет данных в потоке';
if(feof($this->fs))
return false;
while(!preg_match("/\r\n/", $str))
$str = fread($this->fs, $lim);
if($str[0] !== '+')
{
$this->Error = 'Ошибка: '.$str;
return false;
};
if (!$lst)
{
$buff = $str;
return true;
};
while(!preg_match("/.*(\r\n\.\r\n).*/", $str))
$str = $str.fread($this->fs, $lim);
$buff = explode("\r\n", $str);
while((count($buff) > 1)and($buff[count($buff)-1] != '.'))
unset($buff[count($buff)-1]);
if ($buff[count($buff)-1] == '.')
unset($buff[count($buff)-1]);
return true;
}
// запсись в поток и возврат вывода
function Write($snd, &$buff)
{
$this->Error = 'Не открыт ящик';
if (!$this->fs)
return false;
$cmd = explode(' ', $snd);
foreach($cmd as $key => $val)
$cmd[$key] = strtoupper(trim($val));
$buff = '';
$snd = trim($snd)."\r\n";
if(!fwrite($this->fs, $snd))
{
$this->Error = 'Ошибка отсылки команды серверу';
return false;
};
$lst = ((($cmd[0] == "RETR")and(intval($cmd[1]) > 0))or
(($cmd[0] == "LIST")and(!isset($cmd[1])))or
(($cmd[0] == "TOP")and(intval($cmd[1]) > 0)and(intval($cmd[2]) > 0)));
return $this->Read(&$buff, $lst);
}
// открыть ящик
function Open($srv, $usr, $pwd, $auto=true, $port=110, $tm=30)
{
if($this->fs)
{
if(!$auto)
{
$this->Error = 'Подключение уже выполнено';
return false;
};
$this->Close();
};
$this->fs = fsockopen($srv, $port, $errno, $errstr, $tm);
if(!$this->fs)
{
$this->Error = 'Ошибка подключения к почтовому серверу '.$errstr.' ('.$errno.')';
return false;
};
$inf = null;
if (!$this->Read(&$inf))
{
$this->Close();
$this->Error = 'Ошибка получения информации от сервера';
return false;
};
$buff = null;
$snd = "USER ".$usr;
if(!$this->Write($snd, &$buff))
return false;
$snd = "PASS ".$pwd;
if(!$this->Write($snd, &$buff))
return false;
$this->Error = "";
return true;
}
// закрыть работу с ящиком
function Close()
{
$buff = null;
$this->Write("QUIT", &$buff);
if($this->fs)
fclose($this->fs);
$this->fs = false;
}
// список писем
function Lst(&$lst)
{
$this->Error = 'Не открыт ящик';
if (!$this->fs)
return false;
$buff = null;
if(!$this->Write("LIST", &$buff))
return false;
for($i=1; $i<count($buff); $i++)
$lst[$i] = explode(' ', $buff[$i], 2);
return true;
}
// чтение письма
function GetMail($id, &$head, &$text, $del=false)
{
$this->Error = 'Не открыт ящик';
if (!$this->fs)
return false;
$buff = null;
if(!$this->Write("RETR ".$id, &$buff))
return false;
$i = 1;
while(strlen($buff[$i]) > 0)
$head[] = $buff[$i++];
$i++;
while($i < count($buff))
$text[] = $buff[$i++];
if($del)
$this->Write("DELE ".$id, &$buff);
return true;
}
};
$pop3 = new wspPop3();
$opn = $pop3->Open('сервер', 'юзер', 'пасс'); // !!! ПОСТАВИТЬ нужные данные
if ($opn)
{
$head = null;
$text = null;
$mls = array();
$pop3->Lst(&$mls);
foreach($mls as $key => $val)
{
$head = null; $text = null;
if($pop3->GetMail($key, &$head, &$text, false))
ToBase($head, $text);
echo '<hr>';
};
};
$pop3->Close();
unset($pop3);
// функция обработки письма - в частности - занесение в БД
function ToBase($head, $text)
{
// сам процесс занесения информации в БД
$from = null;
foreach($head as $key => $val)
{
if (preg_match("/From/i", $val))
$from = htmlspecialchars($val);
};
echo '<b>'.$from.'</b> Внесено в БД<div style="border:1px solid #FF0000">'.nl2br(htmlspecialchars(implode("\r\n", $text)))."</div>";
};
?>
|
В класс даже не влезай пока - смысла нету... Посмотри концовку, в принципе все что тебе надо, так это массивы $head и $text - в цикле вызова GetMail($key, &$head, &$text, false)...
$key - это идентификатор письма, который получен предварительным $pop3->Lst(&$mls), $head - это заголовочная информация письма, $text - собственно сам текст письма - делай с ним что хочешь, и последний параметр false - это флаг удаления письма после считывания с сервака...
В случае возврата какой-то функцией значения false - смотри свойство Error объекта класса - там описание ошибки... | |
|
|
|
|
|
|
|
для: ZuArt
(06.02.2007 в 18:07)
| | ZuArt спасибо вам огромное - это просто супер, только вот письма с сервера не удаляются....или я что-то упустила. Ошибок не выдаёт.
Я создала кнопку "Загрузить почту" и при повторном нажатии выполняется дублирование содержимого писем в таблицу.. | |
|
|
|
|
|
|
|
для: lilu
(09.02.2007 в 10:31)
| | Вероятно, одно из двух:
Либо при вызове GetMail четвертый параметр не указан как true - признак удаления писем.
Либо не выполнен вызов Сlose() , который дает команду QUIT, завершающую POP3-транзакцию. | |
|
|
|
|
|
|
|
для: Trianon
(09.02.2007 в 10:45)
| | Абсолютно верно =))) забыл, что у меня в коде, када писал параметр оставлял false, чтобы не писать постоянно себе самому =)))
параметр в GetMail действительно должен быть true - он служит флагом удаления писем после их считывания =))) | |
|
|
|
|
|
|
|
для: Trianon
(09.02.2007 в 10:45)
| | Там там же целая функция закрывающая ящик ....
<?
function Close()
{
$buff = null;
$this->Write("QUIT", &$buff);
if($this->fs)
fclose($this->fs);
$this->fs = false;
}
?>
|
P.S. Trianon спасибочки вам за пояснения - я теперь хоть примерно понимаю что к чему.. Хотя ещё разбираться и разбираться...:) | |
|
|
|
|
|
|
|
для: lilu
(09.02.2007 в 10:50)
| | >Там там же целая функция закрывающая ящик
А Вы её вызываете?
Ну, собственно, автор точнее подскажет. | |
|
|
|
|
|
|
|
для: lilu
(09.02.2007 в 10:31)
| | вот в этой строчке
if($pop3->GetMail($key, &$head, &$text, false))
|
поменяйте последний параметр на true =) - будут удаляться... Это флаг удаления писем после считывания =)))
if($pop3->GetMail($key, &$head, &$text, true))
|
ЗЫ. Кстать, протокол РОР3 не удаляет письма сразу, а помечает на удаление... само удаление производится при ПРАВИЛЬНОМ отключении от сервера (командой "QUIT"). Это к тому, что метод класса Close() нужно ОБЯЗАТЕЛЬНО вызывать для корректного завершения работы и удаления обработанных писем =) | |
|
|
|
|
|
|
|
для: ZuArt
(09.02.2007 в 10:54)
| | Всё работает - ура - ну надо же, я бы так не написала ......, спасибочки вам ZuArt и Вам, Trianon..:))). | |
|
|
|
|
|
|
|
для: lilu
(09.02.2007 в 11:22)
| | Нзчт ;) обращайтесь, если что пишите... для индивидуальных вопросов все контакты в профиле есть =))) | |
|
|
|
|
|
|
|
для: lilu
(06.02.2007 в 12:19)
| | Надеюсь ссылки на другие ресурсы тут не считаются запрещенными - посмотри скрипты тут... по идее должны быть раскоментированы хорошо - сам скачать и посмотреть не могу - политика прокси запрещает =(
http://softsearch.ru/programs/18-274-getter-and-sender-download.shtml
А тут описание POP3 http://www.sources.ru/protocols/pop3_learning.shtml | |
|
|
|
|
|
|
|
для: ZuArt
(06.02.2007 в 12:28)
| | Trianon,
По поводу примера, вот что я поняла, если что-то не так - поправьте пож....
define('DEBUG', true); // debug mode
это я так понимаю отладчик включается
что функция send делает не совсем понятно, а вот функция send_rcv кажется формирует то самое сообщение(письмо), кот. в pop3 разделяется точкой.
$fs = fsockopen($server_host, 110, $errno, $errstr, constant('SMTP_TIMEOUT'));
тут всё понятно, имя сервера, 110 порт отправки почты, номер ошибки и номер строки с ошибкой, и истекшее время ожидания при неудачном соед. с сервером ...
А вот потом... начинаются непонятки...
можно как-то пояснить | |
|
|
|
|
|
|
|
для: lilu
(06.02.2007 в 14:21)
| | Функция send_rcv() собственно и реализует обмен данными с сервером согласно протоколу POP3. Она выдает на сервер строки запроса и забирает ответ.
У нее три параметра: первый - сокет, подключенный к нужному серверу,
Второй - строка запроса, которую надо отправить.
И третий - признак запроса с многострочным ответом.
Помимо обмена данными с сервером через сокет, эта функция выводит "на экран" весь диалог в целях отладки, если, как Вы правильно заметили, включен отладочный режим.
Если строка define закомментарена, функция работает "молча".
Возвращать она может следющие вещи:
1)false - если соединение с сервером было неожиданно разорвано.
2) положительный ответ
Например, в ответ на указание имени пользователя в команде USER функция вернет что-то вроде
причем единичка слева приписана функцией sen_rcv() для того чтобы проще было оценивать успех/неудачу запроса.
3) отрицательный ответ
Например, в ответ на некорректный пароль в запросе PASS функция вернет что-то вроде
2 -ERR Authentication failed (bad password?)
|
причем двойка слева приписана функцией sen_rcv() для того чтобы проще было оценивать успех/неудачу запроса.
4) многострочный положительный ответ
Возвращается массив с полученными от сервера строками.
Функция send() - внутренняя, ею пользуется функция send_rcv(). Вам применять её не нужно.
Начавшиеся непонятки это как раз вызовы функции send_rcv() , реализующие диалог. | |
|
|
|
|
|
|
|
для: Trianon
(06.02.2007 в 14:52)
| | Конструкция
if(1 != intval(($s = send_rcv($fs,$c="USER $login")))) die("Status $c: $s");
|
представляет собой вызов send_rcv() с целью отправки однострочного запроса, и проверку на успех выполнения.
По шагам:
а) переменной $c присваивается строка, отправляемая клиентом:
б) результат, который вернул сервер, присваивается переменной $s :
$s = send_rcv($fs,$c...))
|
в) если результат начинается не с единицы
г) ... то мы аварийно завершаем скрипт, печатая, что послал клиент, и что ответил сервер. | |
|
|
|
|