|
|
|
| Здравствуйте!
Использую скрипт для отправки простого сообщения (с локалки):
<?php
$headmess="From: my@mail.com\r\n";
$mailheaders = "Это текст письма";
$smtpmailpath='.'; // Путь до файла smtpmail.php
require($path.'smtpmail.php');
smtpmail('komu@mail.net', "Тема письма", $mailheaders,$headmess);
?>
|
И, собственно, smtpmail.php
<?php
$config['smtp_username'] = 'my@mail.net'; //Имя своего почтового ящика.
$config['smtp_port'] = '25'; // Порт.
$config['smtp_host'] = 'mymail.smtp.net'; //сервер для отправки почты
$config['smtp_password'] = 'pass'; //Пароль
$config['smtp_debug'] = true; //Смотрим ошибки
$config['smtp_charset'] = 'Windows-1251'; //кодировка сообщений. (или UTF-8, итд)
$config['smtp_from'] = 'От меня'; //От кого
function smtpmail($mail_to, $subject, $message, $headers='') {
global $config;
$SEND = "Date: ".date("D, d M Y H:i:s") . " UT\r\n";
$SEND .= 'Subject: =?'.$config['smtp_charset'].'?B?'.base64_encode($subject)."=?=\r\n";
if ($headers) $SEND .= $headers."\r\n\r\n";
else
{
$SEND .= "Reply-To: ".$config['smtp_username']."\r\n";
$SEND .= "MIME-Version: 1.0\r\n";
$SEND .= "Content-Type: text/plain; charset=\"".$config['smtp_charset']."\"\r\n";
$SEND .= "Content-Transfer-Encoding: 8bit\r\n";
$SEND .= "From: \"".$config['smtp_from']."\" <".$config['smtp_username'].">\r\n";
$SEND .= "To: $mail_to <$mail_to>\r\n";
$SEND .= "X-Priority: 3\r\n\r\n";
}
$SEND .= $message."\r\n";
if( !$socket = fsockopen($config['smtp_host'], $config['smtp_port'], $errno, $errstr, 30) ) {
if ($config['smtp_debug']) echo $errno."<br>".$errstr;
return false;
}
if (!server_parse($socket, "220", __LINE__)) return false;
fputs($socket, "EHLO " . $config['smtp_host'] . "\r\n");
if (!server_parse($socket, "250", __LINE__)) {
if ($config['smtp_debug']) echo '<p>Не могу отправить HELO!</p>';
fclose($socket);
return false;
}
fputs($socket, "AUTH LOGIN\r\n");
if (!server_parse($socket, "334", __LINE__)) {
if ($config['smtp_debug']) echo '<p>Не могу найти ответ на запрос авторизаци.</p>';
fclose($socket);
return false;
}
fputs($socket, base64_encode($config['smtp_username']) . "\r\n");
if (!server_parse($socket, "334", __LINE__)) {
if ($config['smtp_debug']) echo '<p>Логин авторизации не был принят сервером!</p>';
fclose($socket);
return false;
}
fputs($socket, base64_encode($config['smtp_password']) . "\r\n");
if (!server_parse($socket, "235", __LINE__)) {
if ($config['smtp_debug']) echo '<p>Пароль не был принят сервером как верный! Ошибка авторизации!</p>';
fclose($socket);
return false;
}
fputs($socket, "MAIL FROM: <".$config['smtp_username'].">\r\n");
if (!server_parse($socket, "250", __LINE__)) {
if ($config['smtp_debug']) echo '<p>Не могу отправить комманду MAIL FROM: </p>';
fclose($socket);
return false;
}
fputs($socket, "RCPT TO: <" . $mail_to . ">\r\n");
if (!server_parse($socket, "250", __LINE__)) {
if ($config['smtp_debug']) echo '<p>Не могу отправить комманду RCPT TO: </p>';
fclose($socket);
return false;
}
fputs($socket, "DATA\r\n");
if (!server_parse($socket, "354", __LINE__)) {
if ($config['smtp_debug']) echo '<p>Не могу отправить комманду DATA</p>';
fclose($socket);
return false;
}
fputs($socket, $SEND."\r\n.\r\n");
if (!server_parse($socket, "250", __LINE__)) {
if ($config['smtp_debug']) echo '<p>Не смог отправить тело письма. Письмо не было отправленно!</p>';
fclose($socket);
return false;
}
fputs($socket, "QUIT\r\n");
fclose($socket);
return TRUE;
}
function server_parse($socket, $response, $line = __LINE__) {
global $config;
while (substr($server_response, 3, 1) != ' ') {
if (!($server_response = fgets($socket, 256))) {
if ($config['smtp_debug']) echo "<p>Проблемы с отправкой почты!</p>$response<br>$line<br>";
return false;
}
}
if (!(substr($server_response, 0, 3) == $response)) {
if ($config['smtp_debug']) echo "<p>Проблемы с отправкой почты!</p>$response<br>$line<br>";
return false;
}
return true;
}
?>
|
Помогите, пожалуйста, именно сюда дописать возможность отправки файла.
Файл находится директорией выше в папке files и всегда называется name_".date('d.m')."_1.xls
(../files/name_".date('d.m')."_1.xls) | |
|
|
|
|
|
|
|
для: Gandzas
(01.03.2007 в 11:44)
| | Так...
вот при таких исходных данных...
$mailtext = "Это текст письма";
$name = "name_".date('d.m')."_1.xls";
$fullname = "..files/".$name;
$headmess="From: my@mail.com\r\n";
|
позволю себе экстракт из http://softtime.ru/scripts/mailattach.php
чтобы не изобретать велосипед.
<?
require($path.'smtpmail.php');
$file = file_get_contents($fullname);
$EOL = "\r\n"; // ограничитель строк
$boundary = "--".md5(uniqid(time())); // любая строка, которой не будет ниже в потоке данных.
$headers = "MIME-Version: 1.0;$EOL";
$headers .= "Content-Type: multipart/mixed; boundary=\"$boundary\"$EOL";
$headers .= "Content-Transfer-Encoding: 7bit";
$headers .= $headmess; // добавим наши заголовки
$multipart = "--$boundary$EOL";
$multipart .= "Content-Type: text/plain; charset=windows-1251$EOL";
$multipart .= "Content-Transfer-Encoding: base64$EOL";
$multipart .= $EOL; // раздел между заголовками и телом текстовой части
$multipart .= chunk_split(base64_encode($mailtext));
$multipart .= "$EOL--$boundary$EOL";
$multipart .= "Content-Type: application/octet-stream; name=\"$name\"$EOL";
$multipart .= "Content-Transfer-Encoding: base64$EOL";
$multipart .= "Content-Disposition: attachment; filename=\"$name\"$EOL";
$multipart .= $EOL; // раздел между заголовками и телом прикрепленного файла
$multipart .= chunk_split(base64_encode($file));
$multipart .= "$EOL--$boundary--$EOL";
smtpmail('komu@mail.net', "Тема письма", $multipart,$headers);
?>
|
как-то так...
Вот только, сдается мне, заголовков в исходных данных явно не хватает....Правда, аттач тут не при чем. | |
|
|
|
|
|
|
|
для: Trianon
(01.03.2007 в 13:37)
| |
smtpmail('komu@mail.net', "Тема письма", $multipart,$headers);
|
Здесь не хватает переменных
$headmess - от кого;
и
$mailheaders - текст письма;
В каком порядке их правильно добавить? | |
|
|
|
|
|
|
|
для: Gandzas
(01.03.2007 в 15:33)
| | Внимательно читайте текст.
эти данные уже там.
Они попадают куда надо соответственно на 12-й и 16-й строках фрагмента -
там где стоит коментарий "добавим наши заголовки"
и под коментарием "раздел между заголовками и телом текстовой части" | |
|
|
|
|
|
|
|
для: Trianon
(01.03.2007 в 16:56)
| | Письмо приходит с вложением, но без: текста, от кого и в теме письма: "Тема пи"
:( | |
|
|
|
|
|
|
|
для: Gandzas
(01.03.2007 в 20:24)
| | В какой кодировке набран сам скрипт? windows-1251?
Одну ошибочку нашел.
В строке
$headers .= "Content-Transfer-Encoding: 7bit";
| не хватает терминатора. Должно быть так:
$headers .= "Content-Transfer-Encoding: 7bit$EOL";
|
Или попробуйте вообще удалить эту строку. | |
|
|
|
|
|
|
|
для: Trianon
(02.03.2007 в 10:20)
| | Текст приходит. А вот поле от кого так и не отображается. :(
И тема письма обрезается. | |
|
|
|
|
|
|
|
для: Gandzas
(09.03.2007 в 15:30)
| | Показывайте фрагмент окончательного скрипта. | |
|
|
|
|
|
|
|
для: Trianon
(09.03.2007 в 15:44)
| | Вот хороший скриптик
<?
class mime_mail {
var $parts;
var $to;
var $from;
var $headers;
var $subject;
var $body;
// создаем класс
function mime_mail() {
$this->parts = array();
$this->to = "";
$this->from = "";
$this->subject = "";
$this->body = "";
$this->headers = "";
}
// как раз сама функция добавления файлов в мыло
function add_attachment($message, $name = "", $ctype = "application/octet-stream") {
$this->parts [] = array (
"ctype" => $ctype,
"message" => $message,
"encode" => $encode,
"name" => $name
);
}
// Построение сообщения (multipart)
function build_message($part) {
$message = $part["message"];
$message = chunk_split(base64_encode($message));
$encoding = "base64";
return "Content-Type: ".$part["ctype"].($part["name"]? "; name = \"".$part["name"]."\"" : "")."\nContent-Transfer-Encoding: $encoding\n\n$message\n";
}
function build_multipart() {
$boundary = "b".md5(uniqid(time()));
$multipart = "Content-Type: multipart/mixed; boundary = $boundary\n\nThis is a MIME encoded message.\n\n--$boundary";
for($i = sizeof($this->parts)-1; $i>=0; $i--) $multipart .= "\n".$this->build_message($this->parts[$i]). "--$boundary";
return $multipart.= "--\n";
}
// Посылка сообщения, последняя вызываемая функция класса
function send() {
$mime = "";
if (!empty($this->from)) $mime .= "From: ".$this->from. "\n";
if (!empty($this->headers)) $mime .= $this->headers. "\n";
if (!empty($this->body)) $this->add_attachment($this->body, "", "text/html; charset=windows-1251");
$mime .= "MIME-Version: 1.0\n".$this->build_multipart();
mail($this->to, $this->subject, $this->body, $mime);
}
}
//Вот и все, привожу пример использования класа:
$attachment = fread(fopen("Ваш файл", "r"), filesize("Ваш файл"));
$dat=date("d-m-Y");
$mail = new mime_mail();
$mail->from = "от кого";
$mail->to = "кому";
$mail->subject = "Загаловок";
$mail->body = "Тело письма";
$mail->add_attachment("$attachment", "Ваш файл", "Content-Transfer-Encoding: base64");
$mail->send();
?>
|
| |
|
|
|
|
|
|
|
для: zerocool
(09.03.2007 в 15:57)
| | Скриптик, может, и хороший :) Только я не вижу здесь использование внешнего smtp | |
|
|
|
|
|
|
|
для: zerocool
(09.03.2007 в 15:57)
| | Этот скриптик тоже не утруждает себя честным оформлением строк заголовков. | |
|
|
|
|
|
|
|
для: Trianon
(09.03.2007 в 15:44)
| | > Показывайте фрагмент окончательного скрипта.
$mailtext = "Нет текста";
$name = 'snimu_'.date('Ymd').'.xls';
$fullname = 'C:/Documents and Settings/Gandzas/Рабочий стол/Base/'.$name;
$headmess="From: my@mail.com\r\n";
$smtpmailpath='.'; // Путь до файла smtpmail.php
require($path.'smtpmail.php');
$file = file_get_contents($fullname);
$EOL = "\r\n"; // ограничитель строк
$boundary = "--".md5(uniqid(time())); // любая строка, которой не будет ниже в потоке данных.
$headers = "MIME-Version: 1.0;$EOL";
$headers .= "Content-Type: multipart/mixed; boundary=\"$boundary\"$EOL$EOL";
$headers .= "Content-Transfer-Encoding: 7bit$EOL";
$headers .= $headmess; // добавим наши заголовки
$multipart = "--$boundary$EOL";
$multipart .= "Content-Type: text/plain; charset=windows-1251$EOL";
$multipart .= "Content-Transfer-Encoding: base64$EOL";
$multipart .= $EOL; // раздел между заголовками и телом текстовой части
$multipart .= chunk_split(base64_encode($mailtext));
$multipart .= "$EOL--$boundary$EOL";
$multipart .= "Content-Type: application/octet-stream; name=\"$name\"$EOL";
$multipart .= "Content-Transfer-Encoding: base64$EOL";
$multipart .= "Content-Disposition: attachment; filename=\"$name\"$EOL";
$multipart .= $EOL; // раздел между заголовками и телом прикрепленного файла
$multipart .= chunk_split(base64_encode($file));
$multipart .= "$EOL--$boundary--$EOL";
smtpmail('komu@mail.net', $name, $multipart, $headers); //$name - здесь ТЕМА письма
print "<br><br>Готово!";
|
| |
|
|
|
|
|
|
|
для: Gandzas
(09.03.2007 в 16:01)
| | В $headmess у Вас написано "From: my@mail.com\r\n"
Я не верю, что в пришедшем письме в строке заголовка "От кого" не стоит my@mail.com.
Или Вы ждете там "от меня"? Эту строку Вы не сформировали.
Сформировать её можно так:
$fromname = 'From me';
$fromaddr = 'my@mail.com';
$headmess="From: $fromname <$fromaddr>\r\n";
| а лучше так (если присутствуют национальные символы) :
$fromname = 'От меня';
$fromname_encoded = base64_encode($fromname);
$fromname_packed = "=?Windows-1251?B?$fromname_encoded?=";
$fromaddr = 'my@mail.com';
$headmess="From: $fromname_packed <$fromaddr>\r\n";
|
А вот с Subject и вправду странно получается.... | |
|
|
|
|
|
|
|
для: Trianon
(09.03.2007 в 16:20)
| | > Я не верю, что в пришедшем письме в строке заголовка "От кого" не стоит my@mail.com.
Не стоИт... В заголовках я изменила только реальный e-mail (куда я отправляю письмо) на "мое мыло", ip, и адрес внешнего смтп.
Хотите, заголовки покажу?
Return-path: <мое мыло>
Envelope-to: мое мыло
Delivery-date: Fri, 09 Mar 2007 15:24:57 +0200
Received: from [мой реальный IP] (helo=smtp сервер, который я использую)
by mail.мой хостер.com with esmtpa (Exim 4.62 (FreeBSD))
(envelope-from <мое мыло>)
id 1HPf5X-000M1y-9K
for мое мыло; Fri, 09 Mar 2007 15:24:57 +0200
Date: Fri, 09 Mar 2007 15:24:45 UT
Subject: =?Windows-1251?B?c25pbXVfMjAwNzAzMDkueGxz=?=
MIME-Version: 1.0;
Content-Type: multipart/mixed; boundary="--c845cb3a8614b1ad48ce26e68d579a0a"
X-Spam_score: -1.7 (-)
X-Spam_report: Content analysis details: (-1.7 points, 5.0 required)
pts rule name description
---- ---------------------- -----------------------------
-1.8 ALL_TRUSTED Passed through trusted hosts only via SMTP
-2.6 BAYES_00 BODY: Bayesian spam probability is 0 to 1%
[score: 0.0000]
0.2 MIME_BASE64_NO_NAME RAW: base64 attachment does not have a file name
1.9 MIME_BASE64_TEXT RAW: Message text disguised using base64 encoding
0.4 SUBJECT_EXCESS_BASE64 Subject: base64 encoded encoded unnecessarily
0.1 TO_CC_NONE No To: or Cc: header
Нет текста
.................
и НИГДЕ нет my@mail.com. | |
|
|
|
|
|
|
|
для: Gandzas
(09.03.2007 в 16:29)
| | Я Вам скажу больше. Я изменила только что $headmess
$fromname = 'От меня';
$fromname_encoded = base64_encode($fromname);
$fromname_packed = "=?Windows-1251?B?$fromname_encoded?=";
$fromaddr = 'my@mail.com';
$headmess="From: $fromname_packed <$fromaddr>\r\n";
|
но поле "от" остается пустым. | |
|
|
|
|
|
|
|
для: Gandzas
(09.03.2007 в 16:29)
| | Может быть дело в smtpmail.php? | |
|
|
|
|
|
|
|
для: Gandzas
(09.03.2007 в 16:35)
| | Похоже, этот чересчур продвинутый не в ту сторону, на мой взгляд, сервер, не любит метод кодирования base64 в заголовках....
Сейчас что-нибудь придумаем в сторону quoted-printable... | |
|
|
|
|
|
|
|
для: Trianon
(09.03.2007 в 16:39)
| | Похоже, Вы правы. Изменила "продвинутый" сервер на другой и все заработало. Поэтому, придумать ничего больше не надо. Спасибо.
Только к теме сообщения добавляется *****SPAM***** ( 7.1 ) | |
|
|
|
|
|
|
|
для: Gandzas
(09.03.2007 в 16:43)
| | Смотрите сами.... :))
Вот вариант с quoted-printable
<?
function qp_encode($s)
{
$r = '';
for($len = strlen($s), $i = 0; $i < $len; $i++)
{
$c = substr($s, $i, 1);
$code = ord($c);
if($code < 0) $code &= 255;
$r .= ($code >= 0x21 && $code < 0x7F && $c != '=' && $c != '?')
? $c : sprintf("=%02X", $code);
}
return $r.'=';
}
$fromname = 'От меня';
$fromname_encoded = qp_encode($fromname);
$fromname_packed = "=?Windows-1251?Q?$fromname_encoded?=";
$fromaddr = 'my@mail.com';
$headmess="From: $fromname_packed <$fromaddr>\r\n";
|
Метод кодирования строки темы тоже можно поменять аналогичным образом. | |
|
|
|
|
|
|
|
для: Trianon
(09.03.2007 в 16:58)
| | Мне без разницы, какой сервер использовать. У меня задача отправить с локалки ОДНО письмо в день на СВОЙ mail, а потом уже работа The Bat... И я так понимаю, не хватает "честности" заголовков, если к теме добавляется подобное сообщение. Честно говоря, оно мне особо не мешает, но хотелось бы понимать почему, в целях самообразования :) Ровно так же, как и quoted-printable. Спасибо!
А в теме сообщения обрезается последний символ. Я уже с таким сталкивалась, но, к сожалению, уже не помню, как я это исправила. В данном случае, поставила после самой темы пробел и она стала отображаться полностью. | |
|
|
|
|
|
|
|
для: Gandzas
(09.03.2007 в 17:04)
| | Не факт, что именно заголовки....
Там судя по тем строкам, которые он сам добавляет, стоит какой-то эвристический анализатор "полезности" письма и считает очки. Анализирует он, конечно никакую не полезность, а лишь свои собственные оценки похожести на роботов....
Ну да хрен с ним...
Если охота разбираться, можно конечно кормить его пачками писем, меняя чуть-чуть оформление каждой строки, пытаясь привести его к письму, сформированному тем же TheBat'ом, и наблюдая за этими самыми очками в каждом пришедшем письме... | |
|
|
|
|
|
|
|
для: Trianon
(09.03.2007 в 17:22)
| | Возвращаясь к нашим баранам. :) В продолжение темы.
При использовании скрипта возникла необходимость зациклить отправку почты, если она не отправилась. т.е. вернула ошибку.
Я это вижу приблизительно так:
do
{
smtpmail('komu@mail.net', "Тема письма", $multipart,$headers);
if ($config['smtp_debug']) sleep(60);
}
while($config['smtp_debug']);
|
Поправьте меня, пожалуйста, если я не права. | |
|
|
|
|
|
|
|
для: Gandzas
(13.03.2007 в 11:54)
| | Невзирая на конкретную причину ошибки?
Чересчур смелое решение. | |
|
|
|
|
|
|
|
для: Trianon
(13.03.2007 в 11:57)
| | ? | |
|
|
|
|
|
|
|
для: Gandzas
(13.03.2007 в 12:03)
| | Отправка письма может быть отклонена по совершенно различным причинам.
К примеру:
1. перегружен сервер.
2. ошибка в адресе отправителя
3. ошибка в логине/пароле отправителя
4. ошибка в адресе получателя
5. переполнен почтовый ящик
6. слишком длинное сообщение
Далеко не в каждом случае попытка повторно отправить письмо решит проблему, не так ли?
В принципе, по кодам диагностики, которые возвращает сервер, можно ориентироваться. Но лишь отчасти. | |
|
|
|
|
|
|
|
для: Trianon
(13.03.2007 в 12:32)
| | >Отправка письма может быть отклонена по совершенно различным причинам.
>К примеру:
>1. перегружен сервер.
Это и есть та проблема, при которой нужна повторная отправка.
>2. ошибка в адресе отправителя
>3. ошибка в логине/пароле отправителя
>4. ошибка в адресе получателя
>5. переполнен почтовый ящик
>6. слишком длинное сообщение
Исключено. Адрес один и он мой. Тела письма нет вовсе, только аттач.
>
>Далеко не в каждом случае попытка повторно отправить письмо решит проблему, не так ли?
Моя проблема в том, что сей процесс происходит рано утром, часов в 6 утра. И, желательно, чтобы письмо ушло без моего участия/поддержки, а сегодня оно не ушло... На какое-то мгновение глюканул хостер и письмо не отправилось, а повторной отправки нет :(
Поэтому желательно, чтобы письмо пыталось отправиться до тех пор, пока не уйдет.
И я где-то допустила ошибку :( Попыталась проверить эту часть кода на практике и в результате письмо отправилось многократно. Пока я не остановила сей процесс... | |
|
|
|
|
|
|
|
для: Gandzas
(13.03.2007 в 12:43)
| |
for($max = 100, $rep = 0; $rep > $max ; ++$rep )
if(smtpmail('komu@mail.net', "Тема письма", $multipart,$headers))
break;
echo "$rep неудачных попыток. ";
echo $rep == $max
? " Письмо так и не отправлено."
: " Письмо отправлено." ;
|
| |
|
|
|
|
|
|
|
для: Trianon
(13.03.2007 в 13:03)
| | Я так понимаю, здесь указано 100 попыток отправки письма, если так и не удалось, то прекращаем попытки.. | |
|
|
|
|
|
|
|
для: Gandzas
(13.03.2007 в 21:05)
| | совершенно верно.
sleep() я забыл. Имеет смысл вставить в тело цикла или в выражение пересчета заголовка. | |
|
|
|