Рубрика «PHP»

Отправка писем через SMTP с авторизацией

В этой заметке рассмотрим как отправлять почту через SMTP с авторизацией с помощью PHP. Рассматривать будем вариант отправки именно с авторизацией, так как SMTP-сервер без авторизации — находка для спаммеров. Потому практически на всех серверах существует обязательная авторизация на исходящие сообщения.

Для начала нам необходим почтовый ящик, зарегистрированный на каком-либо сервере, например mail.ru или yandex.ru и, соответственно логин и пароль от этого ящика. Именно с этого адреса будем отправлять сообщение.

Для отправки письма через SMTP будем использовать сокеты.

<?php
$smtp_server = "smtp.mail.ru";
$port = 25;
$mydomain = "myserver.com";
$username = "user";
$password = "password";
$sender = "me@myserver.com";
$recipient = "joe@company.com";
$subject = "test";
$content = "test";

// Initiate connection with the SMTP server
$handle = fsockopen($smtp_server, $port);
fputs($handle, "EHLO $mydomain\r\n");

// SMTP authorization
fputs($handle, "AUTH LOGIN\r\n");
fputs($handle, base64_encode($username)."\r\n");
fputs($handle, base64_encode($password)."\r\n");

// Send out the e-mail
fputs($handle, "MAIL FROM:<$sender>\r\n");
fputs($handle, "RCPT TO:<$recipient>\r\n");
fputs($handle, "DATA\r\n");
fputs($handle, "To: $recipient\r\n");
fputs($handle, "Subject: $subject\r\n");
fputs($handle, "$content\r\n");
fputs($handle, ".\r\n");

// Close connection to SMTP server
fputs($handle, "QUIT\r\n");
?>

Ссылки по теме:

Загрузка файла на сервер с использованием CURL

Для HTTP запроса типа POST существует два варианта передачи полей из HTML форм, а именно, используя алгоритм application/x-www-form-urlencoded и multipart/form-data. Алгоритм первого типа создавался давным-давно, когда в языке HTML еще не предусматривали возможность передачи файлов через HTML формы.

Со временем возникла необходимость через формы отсылать еще и файлы. Тогда консорциум W3C взялся за доработку формата POST запроса. К тому времени уже достаточно широко применялся формат MIME (Multipurpose Internet Mail Extensions — многоцелевые расширения протокола для формирования Mail сообщений), поэтому, чтобы не изобретать велосипед заново, решили использовать часть данного формата формирования сообщений для создания POST запросов в протоколе HTTP.

Главное отличие multipart/form-data от application/x-www-form-urlencoded в том, что тело запроса теперь можно поделить на разделы, которые разделяются границами (boundary). Каждый раздел может иметь свой собственный заголовок для описания данных, которые в нем хранятся, т.е. в одном запросе можно передавать данные различных типов (как в теле письма можно одновременно с текстом передавать файлы).

Это теория. А теперь практика. Используя библиотеку CURL отправим на сервер POST-запрос типа multipart/form-data:

<?php
$upload = 'image.gif';
$postdata = array( 'name' => 'evgenijj',
                   'email' => 'evgenijj@mail.ru',
                   'message' => 'Какое-то сообщение от пользователя evgenijj',
                   'upload' => "@".$upload );

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://server.com/getfile.php');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_exec($ch);
curl_close($ch);
?>

Файл getfile.php на сервере http://server.com:

<?php
print_r( $_POST );
print_r( $_FILES );
move_uploaded_file ( $_FILES['upload']['tmp_name'], 'image.gif' );
?>

Результат работы:

Array
(
    [name] => evgenijj
    [email] => evgenijj@mail.ru
    [message] => Какое-то сообщение от пользователя evgenijj
)
Array
(
    [upload] => Array
        (
            [name] => image.gif
            [type] => image/gif
            [tmp_name] => C:\WINDOWS\TEMP\php71.tmp
            [error] => 0
            [size] => 100405
        )

)
Array
(
    [url] => http://localhost1/getfile.php
    [content_type] => text/html
    [http_code] => 200
    [header_size] => 193
    [request_size] => 193
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 2.063
    [namelookup_time] => 0
    [connect_time] => 0
    [pretransfer_time] => 0
    [size_upload] => 100943
    [size_download] => 349
    [speed_download] => 169
    [speed_upload] => 48930
    [download_content_length] => 349
    [upload_content_length] => 100943
    [starttransfer_time] => 2
    [redirect_time] => 0
)

Еще один момент: на форуме PHPCLUB.RU встетил упоминание, что может потребоваться указание полного пути файла — иначе CURL выдает ошибку failed creating formpost data.

Ссылки по теме:

Хранение изображений в базе данных MySQL

Для хранения изображений в базе данных MySQL необходимо определить одно из полей таблицы как производное от типа BLOB. Сокращение BLOB означает большой двоичный объект. Тип хранения данных BLOB обладает несколькими вариантами:

  • TINYBLOB - может хранить до 255 байт
  • BLOB - может хранить до 64 килобайт информации
  • MEDIUMBLOB - до 16 мегабайт
  • LONGBLOB - до 4 гигабайт

Соответсвенно, для хранения изображений нам надо создать таблицу images с двумя полями:

  • id - уникальный ID изображения
  • content - поле для хранения изображения

Для сохранения файла изображения в базе данных необходимо прочитать файл в переменную и создать запрос на добавление данных в таблицу. Допустим у нас есть форма для загрузки файла изображения на сервер:

<form enctype="multipart/form-data" method="post" action="putimage.php">
Изображение: <input type="file" name="image" />
<input type="submit" value="Загрузить" />
</form>

Обработчик формы - файл putimage.php:

<?php
// Проверяем пришел ли файл
if( !empty( $_FILES['image']['name'] ) ) {
  // Проверяем, что при загрузке не произошло ошибок
  if ( $_FILES['image']['error'] == 0 ) {
    // Если файл загружен успешно, то проверяем - графический ли он
    if( substr($_FILES['image']['type'], 0, 5)=='image' ) {
      // Читаем содержимое файла
      $image = file_get_contents( $_FILES['image']['tmp_name'] );
      // Экранируем специальные символы в содержимом файла
      $image = mysql_escape_string( $image );
      // Формируем запрос на добавление файла в базу данных
      $query="INSERT INTO `images` VALUES(NULL, '".$image."')";
      // После чего остается только выполнить данный запрос к базе данных
      mysql_query( $query );
    }
  }
}
?>

Извлечь сохраненный файл изображения можно следующим образом (файл image.php):

<?php
if ( isset( $_GET['id'] ) ) {
  // Здесь $id номер изображения
  $id = (int)$_GET['id'];
  if ( $id > 0 ) {
    $query = "SELECT `content` FROM `images` WHERE `id`=".$id;
    // Выполняем запрос и получаем файл
    $res = mysql_query($query);
    if ( mysql_num_rows( $res ) == 1 ) {
      $image = mysql_fetch_array($res);
      // Отсылаем браузеру заголовок, сообщающий о том, что сейчас будет передаваться файл изображения
      header("Content-type: image/*");
      // И  передаем сам файл
      echo $image['content'];
    }
  }
}
?>

Чтобы вывести изображение в HTML-документе, делаем так:

<img src="image.php?id=17" alt="" />

И последнее: графические файлы иногда имеют довольно большой размер, убедитесь, что настройки сервера позволяют работать с таким объемом данных. В файле php.ini это директивы post_max_size - определяет максимальный объем данных передаваемых методом POST, и upload_max_filesize - определяет максимальный размер загружаемого файла. Так же проверьте, позволяют ли настройки MySQL обрабатывать запросы с большим объемом данных (директива max_allowed_packet файла my.ini).