Php руководство по рнр 3 0 функции imap

Содержание

Php руководство по рнр 3 0 функции imap

(PHP 3 >= 3.0.12, PHP 4, PHP 5)

imap_errors — This function returns all of the IMAP errors (if any) that have occurred during this page request or since the error stack was reset

Description array imap_errors ( void )

This function returns an array of all of the IMAP error messages generated since the last imap_errors() call, or the beginning of the page. When imap_errors() is called, the error stack is subsequently cleared.

Пред. Начало След.
imap_deletemailbox Уровень выше imap_expunge

Если Вы не нашли что искали, то рекомендую воспользоваться поиском по сайту:

Php руководство по рнр 3 0 функции imap

error_log — отослать сообщение об ошибке

Описание int error_log(string message, int message_type, string [ destination ], string [ extra_headers ]);

П осылает сообщение об ошибке в web сервер лог, TCP порт или в файл. Первый параметр, message, определяет сообщение об ошибке, которое должно быть отослано. Второй параметр, message_type, определяет способ передачи сообщения:

error_log() лог типы

message посылается в системный лог PHP, используя механизм системного логирования Операционной Системы или в файл, в зависимости от того, как определена конфигурация error_log директивы.
1 message посылается по электронной почте, адрес определен в destination параметре. Только для этого типа сообщений используется параметр extra_headers.Этот тип использует ту же внутреннюю функцию, что и Mail().
2 message отсылается через соединение PHP отладки. Эта опция доступна только тогда, когда установлена remote debugging has been enabled. В этом случае параметр destinationопределяет имя машины или IP адрес и опционально, номер порта, сокета получающего отладочную информацию.
3 message добавляется к файлу, определенному в destination.

Пример. примеры error_log()

error_reporting — устанавливает уровень сообщений об ошибках PHP

Описание int error_reporting(int [ level ]);

У станавливает уровень сообщений об ошибках PHP и возвращает старый уровень. Уровень сообщений об ошибках задается битовой маской и использует следующие значения (используйте линки для получения информации об их назначении):

error_reporting() битовые значения

значение внутреннее имя
1 E_ERROR
2 E_WARNING
4 E_PARSE
8 E_NOTICE
16 E_CORE_ERROR
32 E_CORE_WARNING

getenv — Получить значение переменной среды окружения.

Описание string getenv(string varname);

В озвращает значение переменной среды окружения varname, или false(ложь) в случае ошибки.

$ip = getenv(«REMOTE_ADDR»); // получить ip номер пользователя

get_cfg_var — Получить значение опции конфигурации PHP.

Описание string get_cfg_var(string varname);

В озвращает текущее значение опции конфигурации PHP, заданной в varname, или false(ложь), если произошла ошибка.

Н е возвращает информацию конфигурации, установленную при компиляции PHP, или прочитанную из файла конфигурации Apache (использование php3_configuration_option директив).

Ч то бы проверить, использует ли система php3.ini файл, попробуйте получить значение cfg_file_path. Если оно установлено, то php3.ini файл используется.

get_current_user — Получить имя владельца текущего PHP скрипта.

Описание string get_current_user(void);

В озвращает имя владельца текущего PHP скрипта.

get_magic_quotes_gpc — Получить текущие активные установки magic_quotes_gpc.

Описание long get_magic_quotes_gpc(void);

В озвращает текущие активные установки magic_quotes_gpc. (0 для выключенных(off), 1 для включенных(on))

get_magic_quotes_runtime — Получить текущие активные установки magic_quotes_runtime.

Описание long get_magic_quotes_runtime(void);

В озвращает текущие активные установки magic_quotes_runtime. (0 для выключенных(off), 1 для включенных(on))

getlastmod — Получить время последней модификации страницы.

Описание int getlastmod(void);

В озвращает время последней модификации текущей страницы. Возвращаемое значение — Unix timestamp, подходящее для использование в функции date(). Возвращает false(ложь) при ошибке.

Пример. getlastmod() пример
// выводит что-то вроде этого «Последнее изменение: March 04 1998 20:43:59.»
echo «Последнее изменение: «.date( «F d Y H:i:s.», getlastmod() );

getmyinode — Получить inode текущего скрипта.

Описание int getmyinode(void);

В озвращает inode текущего скрипта, или false(ложь) при ошибке.

getmypid — Получить ID процесса PHP.

Описание int getmypid(void);

В озвращает текущий ID процесса PHP, или false(ложь) при ошибке.

О братите внимание, что при работе PHP как модуля сервера, вы не получите точный IP процесса.

getmyuid — Получить UID владельца скрипта PHP.

Описание int getmyuid(void);

В озвращает UID текущего скрипта, или false(ложь) при ошибке.

phpinfo — Вывод большого количества информации о PHP.

Описание int phpinfo(void);

В ывод большого количества информации о текущем состоянии PHP. Это включает информацию относительно опций компиляции и расширений PHP, версию PHP, информации сервера и среды окружения (если скомпилировано как модуль), среда окружения PHP, информация о версии операционной системы, пути, основных и локальных опций конфигурации, HTTP заголовок и GNU Public License.

phpversion — Получить текущую версию PHP.

Описание string phpversion(void);

В озвращает строку, содержащую версию запущенного в данный момент PHP.

Пример. phpversion() пример
// Печатает что-то вроде этого «Текущая версия PHP: 3.0rel-dev»
echo «Текущая версия PHP: «.phpversion();

putenv — Устанавливает значение переменной среды окружения.

Описание void putenv(string setting);

Д обавляет setting в среду окружения.

Пример. Устанавливает значение переменной среды окружения
putenv(«UNIQ >

set_magic_quotes_runtime — Устанавливает в текущих активных установках конфигурации установки для magic_quotes_runtime.

Описание long get_magic_quotes_runtime(int new_setting);

У станавливает в текущих активных установках конфигурации установки для magic_quotes_runtime. (0 для выключенных(off), 1 для включенных(on))

set_time_limit — Установка лимита на максимальное время работы скрипта

Описание void set_time_limit(int seconds);

У станавливает длительность в секундах, во время которого скрипт должен быть выполнен. Если период превышен, то скрипт возвращает фатальную ошибку. По умолчанию лимит составляет 30 секунд или, если этот параметр установлен, значение max_execution_time в php3.ini. Если значение установлено в ноль(0), то лимит выключен.

П ри вызове, set_time_limit() перезапускает счетчик времени исполнения с нуля. Другими словами, если установлен лимит по умолчанию 30 секунд, и прошло 25 секунд со времени запуска, то после вызова set_time_limit( 20 ) общее время будет составлять 45 секунд после с начала запуска скрипта.

README

Initially released in December 2012, the PHP IMAP Mailbox is a powerful and open source library to connect to a mailbox by POP3, IMAP and NNTP using the PHP IMAP extension. This library allows you to fetch emails from your email server. Extend the functionality or create powerful web applications to handle your incoming emails.

Features

  • Connect to mailbox by POP3/IMAP/NNTP, using PHP IMAP extension
  • Get emails with attachments and inline images
  • Get emails filtered or sorted by custom criteria
  • Mark emails as seen/unseen
  • Delete emails
  • Manage mailbox folders

Requirements

  • PHP 5.6, 7.0, 7.1, 7.2 or 7.3
  • PHP imap extension must be present; so make sure this line is active in your php.ini: extension=php_imap.dll
  • PHP mbstring extension must be present; so make sure this line is active in your php.ini: extension=php_mbstring.dll
  • PHP iconv extension must be present, if mbstring is not available; so make sure this line is active in your php.ini: extension=php_iconv.dll

Installation by Composer

Install the latest available and stable source code from master , which is may not released / tagged yet:

Install the latest available and may unstable source code from develop , which is may not properly tested yet:

PHPUnit Tests

Before you can run the PHPUnit tests you may need to run composer install to install all (development) dependencies.

You can run all PHPUnit tests by running the following command (inside of the installed php-imap directory): php vendor/bin/phpunit —testdox

Integration with frameworks

Getting Started Example

Below, you’ll find an example code how you can use this library. For further information and other examples, you may take a look at the wiki.

Method imap() allows to call any imap function in a context of the the instance:

Some request require much time and resources:

Установка IMAP для PHP 5

Windows

Раскомментируйте (уберите перед строкой точку с запятой) extension=php_imap.dll в php.ini, в переменные среды (Пуск → Настройка → Система → Закладка «Дополнительно» → Переменные среды → Блок «Системные переменные» → Переменная Path → Изменить) добавить в конец строки пути к директории PHP — c:\\ext;c:\;, например, c:\php5\ext;c:\php5;.

Unix/Linux

Расширение IMAP требует установки библиотеки с-client. Прочитать информацию об установке c-client на английском языке можно на php.net.

Быстрая установка c-client для FedoraCore/CentOS:

Установка c-client

Переходим в /usr/local

Скачать последнюю версию c-client можно командой:

В зависимости от версии операционной системы требуется та или иная версия c-client. Например, для ОС FedoraCore 4 потребуется версия imap-2006b.tar.Z, загрузим ее:

Список предыдущих версий c-client можно получить по ftp://ftp.cac.washington.edu/imap/old/.

Переходим в директорию:

Для 64-битных ОС необходимо отредактировать Makefile и заменить в нем EXTRACFLAGS= на EXTRACFLAGS=-fPIC

Выполняем для FedoraCore или RedHat:

или выполняем для FreeBSD:

Для других ОС соответственно «make slx», «make lnp», «make lrh» или «make lsu».

Переходим в директорию c-client/

Примечание: вместо imap-2006b указываете наименование директории в соответствии с выбранной версией c-client.

Установка пакета на примере PHP-5.2.17 для FedoraCore/CentOS

Сборка PHP 5

В Unix системе PHP 5 должен быть сконфигурирован с параметром —with-imap[=DIR]
где DIR — директория с установленным c-client.

Для сборки IMAP c поддержкой SSL необходимо добавить —with-imap-ssl

Перейдем в директорию /tmp

Загрузим последнюю версию PHP 5.2.13:

Перейдем в директорию php-5.2.13

Если был собран eAccelerator, то пересобираем его.

Возможные ошибки при конфигурировании PHP

Если при сборке возникает «configure: error: build test failed. Please check the config.log for details.», то смотрим config.log, в конце может быть указана информация: error: ‘U8T_CANONICAL’ undeclared (first use in this function)

Решение: Выполним копирование libc-client.a

Продолжая использовать сайт, вы даете согласие на обработку файлов Cookies и других пользовательских данных на условиях политики обработки cookie-файлов.

Php руководство по рнр 3 0 функции imap

error_log — отослать сообщение об ошибке

Описание int error_log(string message, int message_type, string [ destination ], string [ extra_headers ]);

П осылает сообщение об ошибке в web сервер лог, TCP порт или в файл. Первый параметр, message, определяет сообщение об ошибке, которое должно быть отослано. Второй параметр, message_type, определяет способ передачи сообщения:

error_log() лог типы

message посылается в системный лог PHP, используя механизм системного логирования Операционной Системы или в файл, в зависимости от того, как определена конфигурация error_log директивы.
1 message посылается по электронной почте, адрес определен в destination параметре. Только для этого типа сообщений используется параметр extra_headers.Этот тип использует ту же внутреннюю функцию, что и Mail().
2 message отсылается через соединение PHP отладки. Эта опция доступна только тогда, когда установлена remote debugging has been enabled. В этом случае параметр destinationопределяет имя машины или IP адрес и опционально, номер порта, сокета получающего отладочную информацию.
3 message добавляется к файлу, определенному в destination.

Пример. примеры error_log()

error_reporting — устанавливает уровень сообщений об ошибках PHP

Описание int error_reporting(int [ level ]);

У станавливает уровень сообщений об ошибках PHP и возвращает старый уровень. Уровень сообщений об ошибках задается битовой маской и использует следующие значения (используйте линки для получения информации об их назначении):

error_reporting() битовые значения

значение внутреннее имя
1 E_ERROR
2 E_WARNING
4 E_PARSE
8 E_NOTICE
16 E_CORE_ERROR
32 E_CORE_WARNING

getenv — Получить значение переменной среды окружения.

Описание string getenv(string varname);

В озвращает значение переменной среды окружения varname, или false(ложь) в случае ошибки.

$ip = getenv(«REMOTE_ADDR»); // получить ip номер пользователя

get_cfg_var — Получить значение опции конфигурации PHP.

Описание string get_cfg_var(string varname);

В озвращает текущее значение опции конфигурации PHP, заданной в varname, или false(ложь), если произошла ошибка.

Н е возвращает информацию конфигурации, установленную при компиляции PHP, или прочитанную из файла конфигурации Apache (использование php3_configuration_option директив).

Ч то бы проверить, использует ли система php3.ini файл, попробуйте получить значение cfg_file_path. Если оно установлено, то php3.ini файл используется.

get_current_user — Получить имя владельца текущего PHP скрипта.

Описание string get_current_user(void);

В озвращает имя владельца текущего PHP скрипта.

get_magic_quotes_gpc — Получить текущие активные установки magic_quotes_gpc.

Описание long get_magic_quotes_gpc(void);

В озвращает текущие активные установки magic_quotes_gpc. (0 для выключенных(off), 1 для включенных(on))

get_magic_quotes_runtime — Получить текущие активные установки magic_quotes_runtime.

Описание long get_magic_quotes_runtime(void);

В озвращает текущие активные установки magic_quotes_runtime. (0 для выключенных(off), 1 для включенных(on))

getlastmod — Получить время последней модификации страницы.

Описание int getlastmod(void);

В озвращает время последней модификации текущей страницы. Возвращаемое значение — Unix timestamp, подходящее для использование в функции date(). Возвращает false(ложь) при ошибке.

Пример. getlastmod() пример
// выводит что-то вроде этого «Последнее изменение: March 04 1998 20:43:59.»
echo «Последнее изменение: «.date( «F d Y H:i:s.», getlastmod() );

getmyinode — Получить inode текущего скрипта.

Описание int getmyinode(void);

В озвращает inode текущего скрипта, или false(ложь) при ошибке.

getmypid — Получить ID процесса PHP.

Описание int getmypid(void);

В озвращает текущий ID процесса PHP, или false(ложь) при ошибке.

О братите внимание, что при работе PHP как модуля сервера, вы не получите точный IP процесса.

getmyuid — Получить UID владельца скрипта PHP.

Описание int getmyuid(void);

В озвращает UID текущего скрипта, или false(ложь) при ошибке.

phpinfo — Вывод большого количества информации о PHP.

Описание int phpinfo(void);

В ывод большого количества информации о текущем состоянии PHP. Это включает информацию относительно опций компиляции и расширений PHP, версию PHP, информации сервера и среды окружения (если скомпилировано как модуль), среда окружения PHP, информация о версии операционной системы, пути, основных и локальных опций конфигурации, HTTP заголовок и GNU Public License.

phpversion — Получить текущую версию PHP.

Описание string phpversion(void);

В озвращает строку, содержащую версию запущенного в данный момент PHP.

Пример. phpversion() пример
// Печатает что-то вроде этого «Текущая версия PHP: 3.0rel-dev»
echo «Текущая версия PHP: «.phpversion();

putenv — Устанавливает значение переменной среды окружения.

Описание void putenv(string setting);

Д обавляет setting в среду окружения.

Пример. Устанавливает значение переменной среды окружения
putenv(«UNIQ >

set_magic_quotes_runtime — Устанавливает в текущих активных установках конфигурации установки для magic_quotes_runtime.

Описание long get_magic_quotes_runtime(int new_setting);

У станавливает в текущих активных установках конфигурации установки для magic_quotes_runtime. (0 для выключенных(off), 1 для включенных(on))

set_time_limit — Установка лимита на максимальное время работы скрипта

Описание void set_time_limit(int seconds);

У станавливает длительность в секундах, во время которого скрипт должен быть выполнен. Если период превышен, то скрипт возвращает фатальную ошибку. По умолчанию лимит составляет 30 секунд или, если этот параметр установлен, значение max_execution_time в php3.ini. Если значение установлено в ноль(0), то лимит выключен.

П ри вызове, set_time_limit() перезапускает счетчик времени исполнения с нуля. Другими словами, если установлен лимит по умолчанию 30 секунд, и прошло 25 секунд со времени запуска, то после вызова set_time_limit( 20 ) общее время будет составлять 45 секунд после с начала запуска скрипта.

Протокол IMAP, или о том, как мы данные из писем вытаскивали

Электронная почта – это важнейший инструмент для обмена информацией и если вы её используете для работы, то наверняка сталкивались с ситуацией: на почту приходит письмо, в котором содержатся данные необходимые для обработки скрипом. Говорить мы будем о Яндекс почте – в этой статье я поделюсь с вами, дорогие читатели, опытом как достать письма из ящика, так же мы разберем вариант, когда в письме есть вложенный файл — как его обнаружить и в итоге скачать для дальнейших манипуляций над ним.

Сам я с этой задачей столкнулся достаточно давно, и тогда при наличии малого опыта работы c почтовыми программами Яндекса потратил массу времени и нервов для достижения требуемого результата. Первая моя ошибка заключалась в том, что, как многие веб-разработчики, я начел интенсивно искать похожие примеры в сети, но не воспользовался самой справкой (помощью) Яндекс. Да, там есть полезная информация, хотя её и очень мало, но она достаточно важная для написания такого рода скрипта (об этом будет ниже). На то время требовалось написать скрипт, суть которого сводилось: на Яндекс почту заказчика приходило письмо с прайсом товаров в xls формате раз в сутки, его необходимо было обработать (распарсить и сравнить с данными из БД интернет магазина и, в зависимости от результата, что-то обновить где-то, отключить или включить).

И первое, что мы сделаем перед написанием скрипта – это наметим наш план действий, который будет состоять из девяти пунктов:

  1. Настроим почту для получения доступа через почтовые протоколы;
  2. Наметим саму структуру PHP приложения и определимся с кодировкой файлов;
  3. Познакомимся с почтовым протоколом IMAP и его возможностями;
  4. Подключимся к Яндекс почте через логин и пароль аккаунта и отследим ошибки на этом этапе;
  5. Обработаем шапку письма;
  6. Получим и обработаем тела письма;
  7. Получим и сохраним вложенные файлы;
  8. Визуализируем проделанную работу;
  9. Сделаем выводы.

Тема довольно объёмная, но я постараюсь изложить всё максимально компактно и понятно. Пожалуй, приступим.

Настройка почты

Переходим в свою почту и заходим в настройки, как показано ниже на скриншоте:

Далее в нижнем правом углу находим ссылку «Почтовые программы» и кликаем по ней:

Теперь мы попали в настройки работы почты через протоколы IMAP и POP3:

Тут многие увидят картину как на изображение выше, но я сталкивался, и не один раз, когда доступы отключены. Поэтому если у вас настройки другие, ставим галочки как на скриншоте, для нас главное разрешить доступ через протокол IMAP.

Структура приложения и её кодировка

В этом примере мы не будем придумывать сложную структуру приложения, так как она не нужна, а добавим только то, что необходимо (я работаю в редакторе Sublime Text):

  • tmp – папка в которую будем загружать вложенные файлы из письма, если они есть;
  • .htaccess – настройка серверной части, если у вас сервер apache;
  • functions.php – сюда будем добавлять наши функции;
  • main.css – файл стилей;
  • index.php – точка входа приложения;

Кодировку будем использовать UTF-8 и поэтому сразу заполним файл .htaccess следующими строками:

Протокол IMAP

Возвращаясь к первому пункту видно, что работать с почтой Яндекс можно также и через протокол POP3. Так почему же именно IMAP? Из двух этих протоков IMAP является более новым и альтернативным POP3, следовательно, у него есть ряд преимуществ (их можно изучить, воспользовавшись википедией), но в нашем случае на выбор повлияло только то, что он более новый. Лично я особой разницы не вижу, что использовать под конкретную задачу получения письма. Если по какой либо причине вам потребуется использовать протокол POP3 то все функции, которые применимы к IMAP будут работать и для него.

Подключаемся к Яндекс почте при помощи протокола IMAP

Для того чтобы подключиться к почте нам нужно знать три параметра: логин почты, её пароль и адрес почтового сервера. Если с двумя параметрами проблем нет, то второй можно найти именно в помощи Яндекс. Об этом (возникшей у меня проблеме) я выше и писал в сети масса примеров, где третий параметр указан не правильно и, представьте себе, что уже на стадии подключения возникают ошибки – это, как минимум, неприятно. Я не буду ходить вокруг да около и сразу дам прямую ссылку на страницу Яндекс – настройка почтовых программ . Вот собственно что нам нужно для подключения:

Теперь можно переходить непосредственно к самому коду:

Первым делом дополнительно указываем кодировку UTF-8 при помощи заголовка и отключаем отображение ошибок. Подключаем файл functions.php и указываем настройки, о которых выше была речь. В массиве $mail_filetypes прописываем форматы файлов, которые нам нужны. Так было решено сделать, чтобы отсеять ненужный мусор, и получать конкретные файлы. Соединение с почтой происходит при помощи функции imap_open(), которая при удачном выполнении возвращает IMAP-поток, а при неудачном — false (но если включить отображение ошибок, то это не так). Завершаем работу с потоками при помощи функции imap_close() передав ей индикатор соединения. Между этими двумя функциями идёт обычный условный оператор.

При удачном соединении при помощи imap_num_msg() узнаем число писем на почте и добавляем массив, в который будем помещать все нам необходимые данные из потока. Далее следует цикл, в котором будет обрабатываться каждое письмо по его номеру (нумерация происходит от 1) по отдельности.

Обработка шапки письма

Для получения шапки письма необходимо воспользоваться функцией imap_header(), вторым параметром которой являет номер письма:

На данном этапе мы получим объект, из которого и будем вытягивать нужные нам данные, сохраняя в массив $mails_data. Вот пример одного из писем:

На этом скриншоте видно, что все данные дублируются, но это особой роли не играет, тянем, то, что удобнее. Намного важнее — кодировка темы письма. Она может быть какой угодно и этот момент надо контролировать. Такая же ситуация и с телом письма и с вложенными файлами.

Сохраняем в нашем массиве: временную метку, дату получения письма, email получателя и отправителя и переходим к получению темы письма. Для этого нам необходимо вначале добавить три функции в файл functions.php:

Названия говорящие и, я думаю, стоит пояснить только последнюю функцию. Она принимает закодированную строку и при помощи imap_mime_header_decode() декодирует ее, в результате чего возвращается массив объектов, у каждого из которых есть два свойства charset (кодировка) и text (текст темы). Дальше всё просто: в цикле проверяя кодировку, приводим к UTF-8 и склеиваем тему в единый заголовок и возвращаем его.

Теперь вернёмся в файл index.php и вытянем последний параметр:

На этом обработка шапки письма будет завершена.

Работаем с телом письма

Продолжаем постепенно формировать наш массив с обработанными данными письма и теперь для получения тела нам необходимо воспользоваться двумя функциями:

В первой переменной $msg_structure находится структура письма – это объект, в котором можно найти массу полезной информации, пример части этого объекта представлен ниже:

Что важно для решения нашей задачи:

  • type – первичный тип тела письма, в зависимости от того, что к нам приходит на почту он может меняться от 0 до 7 (каждой цифре советует свой вид контента который находиться в теле письма);
  • encoding – кодировка трансфера тела, меняется от 0 до 5 (0 — 7BIT, 1 — 8BIT, 2 – BINARY, 3 — BASE64, 4 — QUOTED-PRINTABLE, 5 — OTHER);
  • parts – массив частей письма, который соответствует структуре объекта уровнем выше.

Немного подробнее рассмотрим свойство parts. Первое, что нужно сказать это то, что в нулевой ячейке этого массива находиться информация, соответствующая именно тексту письма, а начиная с первого – вложенным файлам. Также в каждом объекте указывается type и в parameters кодировка в явном и в не явном виде.

Структура письма может быть сколько угодно вложенной, по крайне мере у меня были случаи, когда доходило до четырёх — пяти уровней, поэтому чтобы её, как говорится, раздраконить нам в дальнейшем потребуется написать рекурсивную функцию.

Вторая функция imap_fetchbody() извлекает определённую часть письма, чаще всего в закодированном виде.

Теперь добавим переменную, в которую будем сохранять обработанную версию тела письма:

Вернёмся в файл functions.php и напишем рекурсивную функцию:

Функция recursive_search() принимает один параметр – структуру письма, где последовательно проверяет свойства и достает три параметра: encoding, charset, subtype. Точкой выхода из рекурсии является отсутствие свойства parts с нулевой ячейкой. Больше пояснять тут особо нечего, из кода я думаю понятно, что и как происходит.

Добавим ещё одну функцию для переконвертации тела письма, которая нам потребуется в дальнейшем:

Двигаемся дальше и возвращаемся в файл index.php, где пишем следующий код:

После того, как мы получили данные из рекурсии, постепенно проверяем кодировку трансфера и, в зависимости от этого, вызываем функцию structure_encoding() с соответствующими параметрами. В последнем условном операторе учитываем, то, что мы работает в UTF-8 и если после всех манипуляций у нас получится отличное от кодировки, перекодируем.

Осталось подвести черту:

В теле письма может оказаться, как и обычный текст, так и HTML разметка со своими стилями. Кодируем в BASE64, чтобы при визуализации не поехала уже наша верстка.

Вложенные файлы

Вот, плавно подбираемся к концу написания нашего приложения:

Кусок, отвечающий за обработку вложенного файла гораздо меньше, а теперь — почему именно так. Принцип работы с файлом аналогичен работе с телом письма, только этот этап начинаем с наличия его в массиве свойства parts. Не забываем отсеивать ненужные, сверяясь со списком типов. При помощи нехитрой функции file_put_contents() мы сохраняем наш файл к себе на сервер в папку tmp.

Хочу увидеть результат!

В процессе работы у нас сформировался массив с данными $mails_data, и для визуализации мы уже будем работать непосредственно с ним. В этой статье я использовал тестовое письмо, которое лежало у меня почте, давайте глянем, что у нас получилось в итоге:

Вот какого вида примерно должен у вас получиться массив, увы, пришлось скрыть содержание файла по личным причинам. Теперь переходим к нашей HTML разметке:

Стили я не буду тут добавлять, так как они особой роли не играют, в итоге:

А на сервере в папке tmp у вас появится файл.

Заключение

Проделав все этапы из статьи, вы достигните должного результата, но всё не так просто, как может показаться – есть подводные камни, которые необходимо учитывать. При написании скрипта под конкретную задачу необходимо следить за кодировкой на всех этапах, письма могут идти с различных почт, у каждой из которых могут быть свои нюансы. Так же немаловажным будет учитывать, что Яндекс почта и их документация периодический обновляется, поэтому могут появиться различные подпункты для работы с почтовыми программами. На этом у меня всё, надеюсь вам пригодиться данная статья при работе с более низкоуровневым вариантом Яндекс почты.

Илон Маск рекомендует:  Как поместить прозрачную фоновую каринку на компонент coolbar

Добро пожаловать

В интернете очень много устаревшей информации, которая приводит к заблуждению, распространению неверных решений и написанию плохого кода у начинающих PHP-разработчиков. Это нужно остановить. PHP: Правильный Путь — легкочитаемое руководство для быстрого ознакомления с правилами эффективного использования PHP, принятыми стандартами написания кода и ссылками на признанные руководства по всему интернету.

Переводы

Руководство PHP: Правильный путь уже (или вскоре будет) переведено на множество различных языков:

Дисклеймер

В интернете не существует описания каноничного способа использования PHP. Как бы то ни было, этот скромный сайт содержит лучшие решения, доступные варианты и другую полезную информацию. Он направлен на ознакомление начинающих разработчиков с PHP и переосмысление опытными профессионалами свежих идей.

Это живой документ и он продолжит обновляться более полезной информацией и примерами по мере их появления.

Как внести вклад

Помогите сделать этот сайт лучшим ресурсом для начинающих PHP программистов! Помочь используя GitHub

Расскажите о нас

Руководство PHP: Правильный путь содержит веб-баннеры, которые вы можете использовать на своём сайте. Окажите поддержку, показав начинающим PHP-разработчикам где они могут найти полезную информацию!

Начало

Использование стабильной версии (7.2)

Если вы только начинаете работу с PHP, убедитесь в том, что вы используете текущую стабильную версию PHP 7.2. За последние несколько лет PHP добился больших успехов, добавив новые возможности.

Наиболее часто в ближайшем будущем вы будете видеть, что используются версии PHP 5.x, с последней 5.6. Но вы должны попробовать использовать последнюю стабильную версию, если это возможно. Не дайте скромной разнице между числами 5.2 и 5.6 ввести вас в заблуждение, эта разница представляет важные изменения. Если вам нужна функция или пример её использования, вы всегда можете найти документацию на php.net.

Встроенный веб-сервер

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

Установка на Mac

OSX поставляется с предзапакованным PHP, но, в лучшем случае, он немного отстает от стабильной версии. Lion поставляется с PHP 5.3.6 и Mountain Lion имеет 5.3.10.

Для обновления PHP в OSX вы можете установить его с помощью нескольких пакетных менеджеров, наиболее рекомендуемый из которых php-osx by Liip.

Другой вариант, скомпилировать самостоятельно, в этом случае убедитесь, что у вас установлен либо Xcode, либо его аналог от Apple “CLI для Xcode”, который можно загрузить с Apple Mac Developer Center.

В качестве полного набора «всё-в-одном», который включает PHP, веб-сервер Apache и СУБД MySQL, и всё это с хорошим управлением через GUI, попробуйте MAMP.

Установка в Windows

PHP для Windows можно получить несколькими путями. Вы можете загрузить установочные файлы и, до недавнего времени, вы могли использовать ‘.msi’ установщик. Начиная с PHP версии 5.3.0 установщик не поддерживается.

Для изучения и локальной разработки вы можете использовать встроенный в PHP 5.4+ веб-сервер, о конфигурации которого можно не беспокоиться. Если вы предпочитаете сервера «всё-в-одном», которые включают в себя полноценный веб-сервер и MySQL, тогда можете воспользоваться такими инструментами, как Web Platform Installer, Zend Server CE, XAMPP или WAMP, которые помогут быстро развернуть окружение для разработки в Windows. Но, стоит сказать, что эти инструменты будут отличаться от продакшна, так что будьте осторожны и учитывайте эти различия, если вы работаете на Windows и деплоите на Linux.

Если вам нужно запустить конечную систему на Windows, то IIS7 даст вам лучшую стабильность и производительность. Вы можете использовать phpmanager (плагин для IIS7) для легкого конфигурирования и управления PHP. IIS7 поставляется с встроенным FastCGI, вам нужно просто настроить PHP в качестве обработчика. Для получения помощи и дополнительной информации посетите iis.net.

Vagrant

Запуск вашего приложения в разных окружениях на этапе разработки и продакшна может привести к различным багам, которые дадут о себе знать уже непосредственно при работе приложения. Также сложно поддерживать в разных окружениях стабильные версии для всех библиотек, которые используются при работе в команде разработчиков.

Если вы разрабатываете на Windows и деплоите на Linux (или что-либо отличающееся от Windows) или разрабатываете в команде, вы должны рассмотреть возможность использования виртуальной машины. Это звучит сложно, но, используя Vagrant, вы можете установить простую виртуальную машину всего лишь в несколько шагов. Они могут быть как выполнены вручную, так и с помощью специализированного софта, например, Puppet или Chef, который автоматизирует эту задачу. Использование этого софта гарантирует использование одинаковой конфигурации для нескольких машин, что избавляет вас от необходимости поддержки сложных списков установки. Вы также можете удалить вашу машину, и пересоздать её без большого количества ручных шагов, что делает создание «свежей» виртуалки очень простым.

Vagrant создает общие папки, которые используются для совместного использования кода между вашим хостом и виртуальной машиной, а это означает, что вы можете создавать и редактировать файлы на хосте и позже запускать код в вашей виртуальной машине.

Стандарты написания кода

Сообщество PHP является очень большим и разнообразным, сочетая в себе бесчисленное количество библиотек, фреймворков, и различных компонентов. Для PHP разработчика это обычная практика — выбрать несколько из них и соединить в одном проекте. Очень важно придерживаться общих стандартов написания кода (так точно, насколько это возможно) в своём PHP коде, чтобы позволить разработчикам сочетать и использовать различные библиотеки для своих проектов.

Группа Совместимости Фреймворков предложила и одобрила ряд стилевых рекомендаций, известных как PSR-0, PSR-1 и PSR-2. Не дайте веселым именам смутить вас, эти рекомендации представляют собой набор правил, которых начинают придерживаться такие проекты, как Drupal, Zend, Symfony, CakePHP, phpBB, AWS SDK, FuelPHP, Lithium и другие. Вы можете использовать их при работе над собственным проектом, или в дальнейшем использовать ваш собственный стиль.

В идеале, вы должны писать PHP код, придерживаясь известных стандартов. Это может быть любая комбинация PSR-ов, или один из стандартов кода, сделанных PEAR или Zend. Это позволит другим разработчикам легко читать и работать с вашим кодом, и приложения, которые используют компоненты, смогут сохранить структуру приложения, даже работая с огромным количеством стороннего кода.

Вы можете использовать PHP_CodeSniffer чтобы проверить код на соответствие одной из этих рекомендаций, а также плагин для текстовых редакторов, таких как, к примеру, Sublime Text 2 чтобы получить отчёт в реальном времени.

Используйте PHP Coding Standards Fixer, созданный Фабиеном Потенсьером, для автоматического исправления синтаксиса вашего кода так, чтобы он соответствовал этим стандартам, что спасет вас от исправления каждой проблемы вручную.

Английский язык является наиболее предпочтительным для всех символических имен и инфраструктуры кода. Комментарии могут быть написаны на любом языке, который будет легко читаем текущими и будущими разработчиками, которым предстоит работать над кодом.

Основные моменты языка

Парадигмы программирования

PHP представляет собой гибкий, динамичный язык, который поддерживает несколько техник программирования. Он значительно развился в течение последних нескольких лет: добавлена мощная объектно-ориентированная модель в PHP 5.0 (2004), анонимные функции (замыкания) и пространства имен в PHP 5.3 (2009), а также трейты в PHP 5.4 (2012).

Объектно-ориентированное программирование

PHP реализует очень большой набор особенностей объектно-ориентированного программирования, включая поддержку классов, абстрактных классов, интерфейсов, наследования, конструкторов, клонирования, исключений и т.д.

Функциональное программирование

PHP поддерживает первоклассные функции, т.е. функция может быть применена к переменной. И определенные пользователем, и встроенные функции могут быть применены к переменной и вызываться динамически. Функции могут быть переданы, как аргумент к другой функции (эта особенность называется функцией высшего порядка), а также функция может возвращать другую функцию.

Рекурсия — это особенность, которая позволяет функции вызывать саму себя, это поддерживается языком, но бо́льшая часть кода PHP фокусируется на итерации.

Анонимные функции (замыкания) поддерживаются PHP начиная с версии 5.3 (2009).

В PHP 5.4 добавлена возможность связывать замыкание с областью видимости объекта, а также улучшена поддержка callables (всё, что может быть вызвано), так что они могут быть использованы наравне с анонимными функциями практически во всех случаях.

Meta Programming

PHP поддерживает несколько форм метапрограммирования, что реализуется с помощью таких механизмов, как Reflection API и Магические Методы. Доступно много Магических Методов, например: __get() , __set() , __clone() , __toString() , __invoke() , и т.д., которые позволяют отслеживать поведение внутри класса. Разработчики Ruby часто говорят, что PHP не хватает method_missing , но он доступен, как __call() и __callStatic() .

Пространства имен

Как было сказано выше, сообщество PHP состоит из множества разработчиков, создающих очень много кода. Это значит, что одна библиотека PHP может иметь такое же название класса, как и другая. Когда обе библиотеки используются в одном пространстве имен, они конфликтуют и возникают проблемы.

Пространства имен решают эту проблему. Как описано в руководстве PHP, пространства имен можно сравнить с папками операционной системы, которые являются пространствами имен файлов; два файла с одинаковым именем могут сосуществовать в разных директориях. Подобно этому, два PHP класса с одинаковым названием могут существовать в разных пространствах имен PHP.

Использование пространств имен необходимо для того, чтобы избежать конфликтов при использовании вашего кода с библиотеками других разработчиков.

Один из рекомендуемых способов использования пространств имен описан в PSR-4, который призван обеспечить стандарты для описания файлов, классов и пространств имен, что позволяет создавать подключаемый (plug-and-play) код.

Стандартная Библиотека PHP (SPL)

Стандартная библиотека PHP (SPL) поставляется вместе с PHP и предоставляет набор классов и интерфейсов. Она состоит в основном из часто используемых классов структур данных (стек, очередь, куча, и т.д.), а также итераторов, которые предназначены для прохождения через эти структуры данных или ваши собственные классы, которые реализуют интерфейсы SPL.

Интерфейс командной строки

Главная цель, с которой был создан PHP — это разработка веб-приложений, но он также полезен при написания кода для интерфейса командной строки (CLI). PHP программы командной строки могут помочь вам автоматизировать такие общие задачи, как тестирование, развертывание и администрирование приложения.

CLI PHP программы очень мощные, потому что вы можете использовать код вашего приложения напрямую, без нужды в создании и обеспечении безопасности веб-интерфейса (GUI) для него. Только убедитесь, что вы не используете для ваших скриптов (CLI) корень вашего веб-сервера.

Попробуйте запустить PHP из консоли:

Опция -i выдаст вам конфигурацию вашего PHP, подобно функции phpinfo .

Опция -a предоставляет доступ к интерактивной оболочке, подобно ruby IRB или интерактивной оболочки python. Также существует целый ряд других полезных опций командной строки.

Давайте напишем простую «Привет, $name» программу CLI. Чтобы это сделать, создайте файл с именем hello.php , как показано ниже.

PHP устанавливает две специальные переменные, основанных на аргументах, с которыми запущен ваш скрипт. $argc — это переменная с числовым значением, которая содержит количество переданных аргументов, $argv — это массив, содержащий значение каждого аргумента. Первый аргумент — всегда название вашего PHP скрипта, в этом случае hello.php .

Выражение exit() используется с ненулевым числом, чтобы дать оболочке понять, что команда не удалась. Часто используемые коды завершения можно найти здесь

Для запуска сценария, указанного выше, наберите в командной строке:

XDebug

Один из самых полезных инструментов в разработке программного обеспечения — хороший отладчик. Он позволяет вам отследить исполнение вашего кода и контролировать содержимое вашего стека. XDebug — это PHP отладчик, который может использоваться различными IDE, чтобы дать вам возможность устанавливать Брейкпоинты (точки отладки кода) и контролировать стек. Он также позволяет использовать такие инструменты, как PHPUnit и KCacheGrind, для покрытия кода тестами и его профилирования.

Если вы оказываетесь в безвыходном положении при использовании var_dump/print_r, и у вас не получается найти решение, то возможно вам поможет использование отладчика.

Установка XDebug может оказаться сложной, но одна из самых полезных его функций это «Удаленная отладка» — если вы разрабатываете код локально и затем тестируете его в локальной машине или на другом сервере, Удаленная Отладка — это возможность, которую вы захотите сразу же включить.

Стандартно, вы отредактируете ваш Apache VHost или .htaccess файл со следующими значениями:

“remote_host” и “remote_port” будут указывать на ваш локальный компьютер и порт, который вы указали в вашей IDE для прослушивания. Дальше достаточно включить режим «ожидания соединений» в вашей IDE, и загрузить URL:

Ваша IDE теперь будет перехватывать текущее состояние, позволяя вам устанавливать брейкпоинты и исследовать значения в памяти по мере выполнения скрипта.

Менеджер зависимостей

Существует много библиотек, фреймворков и компонентов PHP на выбор. Ваш проект, скорее всего, будет использовать некоторые из них — это и есть зависимости проекта. До недавнего времени в PHP не существовало удобного способа для управления зависимостями проекта. Даже если вы управляете ими вручную, вам приходилось беспокоиться об автозагрузчиках. Больше это не требуется.

В настоящее время существует две основные системы управления пакетами для PHP — Composer и PEAR. Какая из них подходит именно вам? Ответ — обе.

  • Используйте Composer для управления зависимостями одного проекта.
  • Используйте PEAR для управления зависимостями всех проектов во всей вашей системе.

В общем, пакеты Composer будут доступны только в проектах, для которых вы явно укажете его использование, тогда как пакеты PEAR будут доступны во всех ваших PHP проектах. PEAR, на первый взгляд, может показаться более простым подходом, но есть преимущества в использовании подхода «проект-к-проекту» для зависимостей.

Composer и Packagist

Composer является блестящим менеджером зависимостей для PHP. Укажите список зависимостей вашего проекта в файле composer.json и, с помощью нескольких простых команд, Composer автоматически скачает зависимости вашего проекта и установит для вас автозагрузку.

На данный момент существует много PHP библиотек, которые совместимы с Composer, готовых для использования в вашем проекте. Список этих «пакетов» есть на Packagist, официальном репозитории для Composer-совместимых PHP библиотек.

Как установить Composer

Вы можете установить Composer локально (в вашей текущей рабочей директории; хотя это не рекомендуется) или глобально (например /usr/local/bin). Предположим, вы хотите установить Composer локально. Из корневой директории вашего проекта выполните:

Это позволит загрузить файл composer.phar (бинарный PHP-архив). Вы можете запустить его, используя php для управления зависимостями вашего проекта. Обратите внимание: Если вы скачаете код напрямую в ваш интерпретатор, пожалуйста, сперва прочитайте код онлайн, для подтверждения его безопасности.

Как установить Composer (вручную)

Ручная установка Composer — это продвинутая техника; однако, существуют причины, по которым разработчик может предпочесть именно этот метод использованию интерактивной установки. Интерактивная установка проверяет настройки PHP, чтобы подтвердить, что:

  • Используется необходимая версия PHP
  • Файлы .phar могут быть верно выполнены
  • Определенные права на каталог достаточны
  • Не установлены конфликтные расширения
  • Установлены необходимые настройки php.ini

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

Путь $HOME/local/bin (или другой каталог, выбранный вами) должен находиться в вашей переменной окружения $PATH . Это позволит быть доступной команде composer .

Если вы прочтете документацию Composer, которая гласит, что нужно запускать Composer с помощью команды php composer.phar install , вы можете заменить эту команду на:

Как объявить и установить зависимости

Composer продолжает следить за зависимостями вашего проекта в файле composer.json . Вы можете управлять им вручную, если вам нравится, или же использовать сам Composer. Команда php composer.phar require добавляет зависимость в проект и, если в каталоге нет файла composer.json , он будет создан. Далее мы рассмотрим пример, который добавляет Twig, как зависимость вашего проекта. Запустите это в корневой директории вашего проекта, куда вы загружали composer.phar :

Аналогично команда php composer.phar init проведет вас через создание полного файла composer.json для вашего проекта. Есть и другой путь, когда вы создадите файл composer.json вы можете сказать Composer, чтобы он скачал все ваши зависимости в папку vendors/ . Это также применимо для проектов, которые вы загрузили и которые предоставляют файл composer.json :

Затем добавьте этот код в основной PHP-файл вашего приложения; это укажет PHP использовать автозагрузчик Composer для зависимостей вашего проекта.

Теперь вы можете использовать зависимости вашего проекта и они будут автоматически загружаться (по требованию).

Обновление зависимостей

Composer создает файл composer.lock который хранит точную версию каждого пакета, который он загрузил во время первого запуска php composer.phar install . Если вы поделились проектом с другими разработчиками и файл composer.lock является частью него, то при запуске php composer.phar install они получат ту же версию, что и вы. Чтобы обновить ваши зависимости запустите php composer.phar update .

Очень удобно гибко указывать требуемые версии. Если вы нуждаетесь в версии

1.8, что значит “всё что новее 1.8.0, но меньше 2.0.x-dev”. Вы также можете использовать шаблон * , например 1.8.* . Теперь команда Composer php composer.phar update обновит все ваши зависимости до новейших версий, которые соответствуют указанным ограничениям.

Проверка ваших зависимостей на безопасность

Security Advisories Checker является веб-сервисом и инструментом командной строки, оба из которых изучают ваш файл composer.lock и сообщают, если есть необходимость в обновлении какой-либо из ваших зависимостей.

Другим ветераном среди пакетных менеджеров, которым наслаждаются многие PHP-разработчики, является PEAR. Он работает практически так же, как и Composer, но имеет несколько важных отличий.

PEAR требует, чтобы каждый пакет имел определенную структуру, это означает, что автор пакета должен подготовить его для использования с PEAR. Использование проекта, который не был подготовлен для работы с PEAR невозможно.

PEAR устанавливает пакеты глобально, что означает то, что после установки, они доступны всем проектам на этом сервере. Это может быть полезно, если много проектов строятся на тех же пакетах с той же версией, но может привести к проблемам, если проекты разрабатывались для разных версий.

Как установить PEAR

Вы можете установить PEAR, загрузив установщик phar и выполнив его. Документация PEAR содержит подробную инструкцию по установке для каждой операционной системы.

Если вы используете Linux, вы также можете посмотреть наличие PEAR в пакетном менеджере вашего дистрибутива. Debian и Ubuntu, к примеру, содержат информацию о пакете php-pear в пакетном менеджере apt.

Как установить пакет

Если пакет существует в списке пакетов PEAR, вы можете установить его, указав официальное название:

Если пакет выложен на другом канале, вам нужно сначало сделать discover этого канала и затем указать его во время установки. Подробнее об этом в использование каналов.

Обработка зависимостей PEAR с Composer

Если вы уже используете Composer и желаете установить какой-то код из PEAR, вы можете использовать Composer для обработки зависимостей PEAR. Этот пример установит код из pear2.php.net :

Первый раздел «repositories» даст понять Composer, что он должен сделать “initialise” (или “discover” в терминологии PEAR) репозиторий pear. Затем секция require укажет именам пакетов префикс, как ниже:

Префикс “pear” жестко ограничен, чтобы избежать любых конфликтов, так как каналы Pear могут быть схожи с другими поставщиками пакетов например, вместо короткого имени (или полного URL) может быть использовано для объявления в каком канале находится пакет.

Когда код будет установлен он будет доступен в вашей папке vendor и автоматически доступен через автозагрузчик (файл Autoload) Composer.

Чтобы использовать этот пакет PEAR просто объявите как ниже:

Практики написания кода

Основы

PHP — это обширный язык, который позволяет разработчикам всех уровней писать код не только быстро, но и эффективно. В любом случае, изучая язык, мы нередко забываем основы, которые мы изучали изначально (или бегло просмотрели), в пользу коротких путей и/или вредных привычек. Чтобы помочь в борьбе с этой общей проблемой, эта секция предназначена для напоминания разработчикам основ практик написания кода PHP.

Дата и время

PHP содержит встроенный класс DateTime, предназначенный для чтения, записи, сравнения и вычисления даты или времени. Также в PHP много функций, связанных с датой и временем, помимо класса DateTime, но класс предоставляет хороший объектно-ориентированный интерфейс для решения большинства задач. Он способен даже обрабатывать временные зоны, но это уже не рассматривается в данном коротком введении.

Для начала работы с DateTime, сконвертируйте «сырую» строку даты и времени в объект с помощью фабричного метода createFromFormat() или выполните new \DateTime , чтобы получить текущую дату и время. Используйте метод format() для конвертирования DateTime обратно в строку для вывода.

Вычисления с DateTime возможны с использованием класса DateInterval. У класса DateTime есть методы add() и sub() , которые принимают DateInterval, как аргумент. Не пишите код, который ожидает одинаковое число секунд каждый день, перевод часов и смена часовых поясов разрушат это предположение. Вместо этого используйте интервалы дат. Для расчета разницы между датами используйте метод diff() . Он вернет новый объект DateInterval, который очень легко отобразить.

С объектами DateTime, вы можете использовать стандартные методы сравнения:

И последний пример для демонстрации класса DatePeriod. Он используется для перебора повторяющихся событий. Класс может принимать два объекта DateTime, начало и конец, и интервал, для которого он вернет все события между ними.

Design Patterns

При построении приложения полезно использовать в коде шаблоны, а также придерживаться некоторых стандартов для всей структуры проекта. Использование шаблонов полезно, потому что оно упрощает управление кодом, а также позволяет другим разработчикам быстро понять, как всё взаимодействует друг с другом.

Если вы используете фреймворк, то большинство высокоуровневого кода и структура проекта будет основываться на архитектуре фреймворка, поэтому большинство решений относительно шаблона сделано за вас. Но всё же наиболее верным решением будет выбрать наиболее подходящие шаблоны и следовать им в коде, который вы пишете на базе фреймворка. С другой стороны, если вы не используете фреймворк для построения приложения, тогда вы должны найти шаблоны, которые наилучшим образом соответствуют типу и размеру приложения, которое вы создаете.

Исключения

Исключения — это неотъемлемая часть большинства популярных языков программирования, но зачастую PHP разработчики не уделяют им должного внимания. Языки, подобные Ruby, очень подробно обрабатывают исключения, поэтому, если что-то идёт не верно, например: не удался HTTP запрос, запрос к базе данных происходит неправильно или если запрошенное изображение не было найдено, Ruby (или используемые гемы) выбросит исключение на экран, помогающее понять где вы допустили ошибку.

PHP сам по себе довольно слаб в плане этого и вызов file_get_contents() , как правило, даст вам только FALSE и предупреждение. Многие устаревшие PHP-фреймворки, как CodeIgniter, просто вернут false, добавят сообщение в свой собственный журнал и, может быть, дадут вам использовать метод, как $this->upload->get_error() , чтобы посмотреть, что пошло не так. Проблема в том, что вы должны искать ошибку и проверять документацию, чтобы понять, какой ошибочный метод существует в этом классе, вместо того, чтобы сделать это всё более очевидным.

Еще одна проблема в том, что классы автоматически выдают ошибку на экран и закрывают процесс. Когда вы делаете это, вы не даете другому разработчику динамически обработать эту ошибку. Исключения должны быть выброшены, чтобы дать разработчику знать об ошибке и выбрать, как её обработать. Например:

Исключения SPL

Универсальный класс Exception предоставляет очень мало отладочного контекста для разработчика; как бы то ни было, для того чтобы исправить это, можно создать специализированный класс, который будет расширять возможности универсального класса Exception :

Это означает, что вы можете добавить несколько блоков отлова и обрабатывать разные исключения по-разному. Это может привести к созданию множества изменённых Исключений, некоторые из которых можно было бы избежать, используя Исключения SPL, предоставляемые расширением SPL.

Например, если вы используете магический метод __call() и вами был вызван неизвестный метод, то вместо выбрасывания стандартного исключения, которое очень расплывчато, или вместо создания своего исключения, вы можете просто использовать throw new BadFunctionCallException; .

Базы данных

Скорее всего, ваш PHP код будет использовать базу данных для сохранения информации. Существует несколько вариантов для подключения и взаимодействия с базой данных. Рекомендуемым вариантом до PHP 5.1.0 было использование нативных (родных) драйверов, таких как mysql, mysqli, pgsql, etc.

Встроенные драйвера замечательны, если вы используете ОДНУ базу данных в ваших приложениях, но если, например, вы используете MySQL и немного MSSQL, или вам нужно подключиться в базе данных Oracle, тогда вы не сможете использовать те же драйвера. Вам нужно будет изучить новый API для каждой базы данных — и это может оказаться нерациональным.

Обратите внимание, что расширение mysql для PHP больше не поддерживается, и его официальным статусом, начиная с PHP версии 5.4.0, является «Устарело в связи с длительным сроком использования». Это значит, что оно будет удалено в течение нескольких следующих релизов, так что в PHP 5.6 (или в версиях, следующих за 5.5) оно вполне может пропасть. Если вы используете mysql_connect() и mysql_query() в своих приложениях, тогда вам придется столкнуться с переписыванием кода, поэтому лучшим вариантом сейчас является использование в приложениях mysqli или PDO вместо mysql, прежде чем вы в дальнейшем столкнётесь с нерабочими приложениями. Если вы начинаете изучение баз данных с нуля, тогда полностью откажитесь от использования расширения mysql — используйте Расширение MySQLi или PDO.

PDO — это абстрактная библиотека для подключения к базе данных, встроенная в PHP с версии 5.1.0, которая обеспечивает единый интерфейс для взаимодействия с большим количеством различных баз данных. PDO не будет переводить ваши SQL запросы или эмулировать отсутствующие возможности; он чист для подключения к нескольким типам баз данных с тем же API.

Более важно, что PDO позволяет вам безопасно вводить пользовательские данные (например идентификатор) в ваши SQL запросы, без беспокойства о SQL-инъекциях. Это возможно благодаря использованию PDO выражений и связывания (bound) параметров.

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

Это ужасный код. Вы вставляете необработанные параметры в SQL запрос. Это приведёт к взлому. Просто представьте, что взломщик сделает запрос http://domain.com/? >, который присвоит переменной $_GET[‘id’] значение 1;DELETE FROM users и приведёт к удалению всех ваших пользователей! Вместо этого, вы должны очистить ввод идентификатора с помощью связывания параметров PDO.

Это правильный код. Он использует связанный параметр в выражении PDO. Это позволяет избежать ввода некоректного ID перед тем, как передать запрос в базу данных, тем самым предотвращая потенциальные SQL-инъекции.

Вы также должны понимать, если подключение не закрыто должным образом, то оно использует много ресурсов, которые тратятся впустую, впрочем это больше относится к другим языкам. Используя PDO, вы можете неявно закрывать подключение уничтожив объект — все ссылки на него будут удалены, т.е. установлены в NULL. Если не сделать этого явно, PHP закроет подключение за вас, когда выполнение скрипта завершится, если только вы не используете постоянные подключения.

Уровни абстракции

Многие фреймворки предоставляют собственный уровень абстракции, который может строиться на основе PDO. Такая фактическая абстракция баз данных позволяет оборачивать запросы на PHP в методы, которые отсутствуют в одной системе баз данных, но работают в другой. Это, конечно, добавит небольшие накладные расходы, но если вы строите портативные приложения, которым необходима работа с MySQL, PostgreSQL и SQLite, тогда, для чистоты кода, минимальными накладными расходами можно пренебречь.

Некоторые уровни абстракции построены с использованием PSR-0 стандарта, поэтому могут быть установлены в любое приложение:

Безопасность

Безопасность веб-приложений

Есть плохие люди, которые могут и хотят взломать ваши веб-приложения. Важно принять необходимые меры предосторожности, чтобы укрепить безопасность вашего приложения. К счастью, прекрасные люди в The Open Web Application Security Project (OWASP) составили полный список известных проблем безопасности и методов защиты от них. Это должно быть прочитано любым разработчиком, заботящимся о безопасности.

Хэширование паролей

Наверное, каждый PHP-разработчик занимается разработкой приложений, которые нуждаются в пользовательской авторизации. Имя пользователя и пароль хранятся в базе данных и позже используются для авторизации пользователя.

Илон Маск рекомендует:  Предопределённые константы mcrypt

Очень важно правильно хэшировать пароль перед его сохранением. Хэширование пароля является необратитым, односторонняя функция применяется на пользовательских паролях. Она возвращает строку определенной длины, которую невозможно расшифровать. Это значит, что вы можете сравнить один хэш с другим, чтобы понять, что они пришли из одной и той же исходной строки, но вы не можете определить оригинальную строку. Если ваши пароли не захэшированы, и доступ к базе данных получен третьй стороной, то ваши пользовательские аккаунты теперь скомпрометированы. Некоторые пользователи (к сожалению) могут использовать один и тот же пароль для разных сервисов. Как бы то ни было, очень важно серьезно относиться к безопасности.

Хэширование паролей с функцией password_hash

В PHP 5.5 была представлена функция password_hash . Сейчас она использует BCrypt, сильнейший алгоритм, поддерживаемый PHP. Она будет обновлена в будущем, для поддержки бОльшего числа алгоритмов, по мере необходимости. Библиотека password_compat была создана для обратной совместимости с PHP >= 5.3.7.

Ниже мы хэшируем строку и далее сверяем её с новой строкой. Поскольку наши две исходные строки отличаются (‘secret-password’ и ‘bad-password’) эта авторизация будет неудачной.

Фильтрация данных

Никогда не доверяйте пользовательскому вводу, который передаётся вашему PHP коду. Всегда проверяйте и очищайте пользовательский ввод перед его использованием в коде. Функции filter_var и filter_input помогут очистить переменные, а также проверить соответствие введённых данных некоторому формату (например, адрес электронной почты).

Пользовательский ввод может быть различным: $_GET и $_POST , данные введённые в форму, некоторые значения в суперглобальной переменной $_SERVER и тело HTTP запроса, открытое с помощью fopen(‘php://input’, ‘r’) . Запомните, что пользовательский ввод не ограничивается данными формы, отправленной пользователем. Отправляемые и загружаемые файлы, значения сессий, данные cookie и данные сторонних веб-сервисов также приравниваются к пользовательскому вводу.

Хотя пользовательские данные могут быть без проблем сохранены, скомбинированы и к ним может быть получен доступ позже, они всё ёще являются пользовательским вводом. Каждый раз, когда вы что-либо обрабатываете, объединяете или подключаете данные в ваш код, спросите себя, отфильтрованы ли эти данные и можно ли им доверять.

Данные могут быть отфильтрованы по-разному, в зависимости от их назначения. Например, когда нефильтрованные данные, введённые пользоватем, передаются в HTML код страницы, он может выполнить HTML и JavaScript на вашем сайте! Этот тип атаки известен, как Cross-Site-Scripting (XSS) и может иметь очень серьёзные последствия. Один из способов избежать XSS заключается в очистке ввода от всех HTML тэгов (их удалением, или заменой на HTML символы) с помощью функции strip_tags или экранирование символов в равносильные им HTML сущности с функцией htmlentities или htmlspecialchars .

Другой пример, передача данных для выполнения командной строкой. Это может быть крайне опасно (и, как правило — это плохая идея), но вы можете использовать встроенную функцию escapeshellarg для очистки аргументов командной строки.

Последний пример, принимает пользовательский ввод, чтобы определить, какой файл загружать из файловой системы. Это может быть использовано для изменения имени файла на путь файла. Вам нужно убрать “/”, “../”, нулевые байты или другие символы из пути файла, так чтобы скрипт не мог загружать скрытые, непубличные или конфиденциальные файлы.

Санитизация

Санитизация удаляет (или экранирует) неправильные или небезопасные символы из пользовательского ввода.

Например, вам необходимо нормализовать пользовательский ввод перед подключением ввода в HTML или его вставкой в сырой SQL запрос. Когда вы используете связанные параметры с PDO, они будут очищать ввод за вас.

Иногда требуется разрешить некоторые безопасные HTML тэги в вводе, когда он подключается в HTML страницу. Это очень трудно сделать и многие избегают этого, используя ограниченное форматирование, как например Markdown или BBCode, либо библиотеки с белым списком, как HTML Purifier, существующие по этой причине.

Валидация

Валидация гарантирует, что пользовательский ввод, является тем, что вы ожидаете. Например, вы можете валидировать адрес электронной почты, номер телефона или возраст при обработке запроса регистрации.

Конфигурационные файлы

Когда вы создаёте файлы конфигурации для ваших приложений, рекомендуется использование одного из следующих способов:

  • Рекомендуется хранить вашу конфигурационную информацию там, где к ней не может быть получен доступ напрямую, а доступ к ней осуществлялся через файловую систему.
  • Если вы вынуждены хранить конфигурационные файлы в корневом каталоге, именуйте файл с расширением .php . Это гарантирует, что, если к скрипту обратятся напрямую, он не будет выведен, как обычный текст.
  • Информация в файлах конфигурации, должна быть защищена соответственно, либо с помощью шифрования или системных прав группы/пользователя файла.

Использование глобальных переменных

Примечание: С появлением PHP 5.4 директива register_globals была удалена и больше не может быть использована. Это касается тех, кому нужно обновить старое приложение.

Включенный параметр конфигурации register_globals делает несколько типов переменных (в том числе из $_POST , $_GET и $_REQUEST ) глобальными, доступными в глобальной области видимости вашего приложение. Это может легко привести к проблемам с безопасностью, поскольку ваше приложение не сможет эффективно определить откуда пришли данные.

Например : $_GET[‘foo’] будет доступна через $foo , которая может заместить переменную, которая не была объявлена. Если вы используете PHP register_globals off (выключена).

Сообщения об ошибках

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

Разработка

Для того, чтобы видеть все возможные ошибки во время разработки, настройте следующие параметры в вашем php.ini :

Установка значения в -1 покажет каждую возможную ошибку, даже если новые уровни и константы будут добавлены в новых версиях PHP. Константа E_ALL ведёт себя так-же в PHP 5.4. — php.net

Константа уровня ошибок E_STRICT была введена в 5.3.0 и не является частью E_ALL , как бы то ни было, она стала частью E_ALL в 5.4.0 Что это значит? Для вывода всех возможных ошибок в версии 5.3 вам нужно использовать либо -1 либо E_ALL | E_STRICT .

Вывод всех ошибок разными версиями PHP

  • -1 or E_ALL
  • 5.3 -1 or E_ALL | E_STRICT
  • > 5.3 -1 or E_ALL

Продакшн

Чтобы спрятать все ошибки вашей среды во время продакшна, настройте ваш php.ini следующим образом:

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

Тестирование

Написание автоматизированных тестов для вашего кода PHP, считается наилучшей практикой. Автоматизированные тесты являются отличным инструментом для подтверждения того, что ваше приложение не сломается, когда вы внесёте изменения или добавите новую функциональность.

Существует несколько различных типов инструментов тестирования (или фреймворков) доступных для PHP, которые используют различные подходы — все, пытаются избежать ручного тестирования и нуждаются в больших командах проверки качества, чтобы убедиться, что изменения не сломают существующую функциональность.

Тесто-ориентированная разработка

Разработка через тестирование (TDD) представляет собой процесс разработки программного обеспечения, который опирается на повторении очень короткого цикла разработки: сперва, разработчик пишет автоматизированные тесты, которые определяют желаемое улучшение или новую функцию, далее производит код, который успешно пройдет этот тест и наконец производит рефактор кода для соответствия стандартам. Kent Beck, человек которому приписывают статус разработчика или “переоткрывателя” техники, TDD предлагает простую конструкцию, а также вселяет уверенность.

Существует несколько различных типов тестирования, которые вы можете сделать для вашего приложения.

Модульное тестирование (Unit Testing)

Модульное тестирование — это подход к программированию, который позволяет удостовериться, что функции, классы и методы работают, как ожидается с момента начала и до конца разработки. Проверяя значения, которые приходят и выходят из различных функций и методов, вы можете быть уверены, что внутренняя логика работает правильно. Используя Внедрение Зависимостей и внедрение классов «макетов» и заглушек, вы можете убедиться, что зависимости используются правильно для большего покрытия тестами.

При создании класса или функции, вы должны создать модульный тест для каждого возможного поведения. На базовом уровне, вы должны убедиться, что ваш код выдаёт ошибку, если вы отсылаете неправильные аргументы и работает, если вы отсылаете правильные аргументы, соответственно. Это поможет убедиться в том, что изменения, которые вы сделаете относительно этого класса или функции позднее не помешают старым работать как ожидалось. Единственная альтернатива этому var_dump() в test.php, который не является способом создания приложений — больших или маленьких.

Ещё одно использование модульных тестов — вклад в open source. Если вы можете писать тесты, которые показывают сломанную функциональность, тогда почините её, и покажите, что тест пройден, патчи имеют больше шансов быть принятыми. Если вы запускаете проект, который допускает Pull Request, тогда вы должны указать это в качестве требования.

PHPUnit является фреймворком тестирования стандарта де-факто для написания модульных тестов в PHP приложениях, но также существует несколько альтернатив.

Интеграционное тестирование

Интеграционное тестирование (иногда называется Интеграция и Тестирование, с аббревиатурой “I&T”) это фаза в тестирование програмнного обеспечения, в котором отдельные модули, комбинируются и тестируются, как группа. Это происходит после модульного тестирования и перед валидационным тестированием. Integration testing takes as its input modules that have been unit tested, groups them in larger aggregates, applies tests defined in an integration test plan to those aggregates, and delivers as its output the integrated system ready for system testing.

Многие инструменты, которые могуть быть использованы для модульного тестирования, также могут быть использованы для интеграционного тестирования, поскольку используются схожие принципы.

Функциональное тестирование

Также известное, как подтверждающее тестирование, функциональное тестирование состоит из использования инструментов для создания автоматизированных тестов, которые по-настоящему используют ваше приложение, а не просто проверяют, что отдельные куски (модули) кода ведут себя и могут взаимодействовать правильно. Эти инструменты обычно работают, используя реальные данные и симулируя реальных пользователей приложения.

Инструменты функционального тестирование

  • Selenium
  • Mink
  • Codeception это фреймворк для тестирования (всё-в-одном), включающий инструменты подтверждающего тестирования

Поведенческо-ориентированная разработка

Существует две разновидности Поведенческо-ориентированной разработки (BDD): SpecBDD и StoryBDD. SpecBDD концентрируется на техническом поведении или коде, в то время как StoryBDD концентрируется на деле, будущем поведении или взаимодействии. PHP имеет фреймворки для обоих типов BDD.

Используя StoryBDD, вы пишите читаемые людьми истории, которые объясняют поведение вашего приложения. Эти истории могут быть запущены, как актуальные тесты для вашего приложения. Фреймворк, используемый в PHP приложениях для StoryBDD — Behat, который вдохновлён проектом для Ruby Cucumber и реализует Gherkin DSL для объяснения особенностей поведения.

Вместе со SpecBDD, вы пишите спецификацию, которая объясняет, как ваш код должен себя вести. Вместо тестирования функции или метода, вы объясняете, как эта функция или метод должен себя вести. PHP предлагает фреймворк PHPSpec для данных целей. Этот фреймворк вдохновлён проектом RSpec для Ruby.

Инструменты

  • Behat, StoryBDD фреймворк для PHP, вдохновлённый проектом для Ruby Cucumber;
  • PHPSpec, SpecBDD фреймворк для PHP, вдохновлённый проектом для Ruby RSpec;
  • Codeception это фреймворк для тестирования (всё-в-одном), использующий принципы BDD;

Дополнительные инструменты тестирования

Помимо индивидуального тестирования и поведенческо-ориентированных фрэймворков, существует ряд общих фреймворков и вспомогательных библиотек, полезных для любого предпочтительного подхода.

Инструменты

  • Selenium автоматизационный инструмент для браузера интегрируемый с PHPUnit
  • Mockery Mock Object Framework интегрируемый с PHPUnit или PHPSpec

Сервера и развертывание

PHP приложения могут быть развернуты и запущены на продакшн веб-сервере рядом способов.

Платформа, как сервис (PaaS)

PaaS предоставляет системную и сетевую архитектуры, необходимые для запуска PHP приложений в веб. Это означает, как минимум, отсутствие настройки для запуска PHP приложений или PHP фреймворков.

В недавнее время PaaS стал очень популярным методом для развертывания, хостирования и расширения PHP приложений всех размеров. Вы можете найти список провайдеров PHP PaaS в нашей ресурсной секции.

Виртуальный или выделенный сервер

Если вы знакомы с администрированием системы, или заинтересованы в его изучении, виртуальный или выделенный сервер даст вам полный контроль над средой продакшна вашего приложения.

nginx и PHP-FPM

PHP, через встроенный в него менеджер процессов FastCGI (FPM), очень хорошо сочетается с nginx, который является легковесным и высокопроизводительным веб-сервером. Он использует меньше памяти, чем Apache и может лучше обрабатывать конкурентные запросы. Это особенно важно на виртуальном сервере, для которого может быть критичен объем используемой памяти.

Apache и PHP

PHP и Apache имеют длинную совместную историю. Apache широконастраиваемый и имеет большое количество доступных модулей для расширения функциональности. Это очень популярный выбор для виртуальных хостингов и лёгкой установки PHP фреймворков и приложений с открытым исходным кодом, как WordPress. К сожалению, Apache использует больше ресурсов, чем nginx, и не может выдержать столько же посетителей одновременно.

Apache имеет несколько возможных конфигураций для запуска PHP. Самая популярная и лёгкая для установки prefork MPM вместе с mod_php5. Хотя это не самое эффективное в отношении памяти решение, оно очень просто для установки и использования. Наверное, это лучшее решение, если вы не хотите углубляться в серверное администратирование. Если вы хотите использовать mod_php5, вы обязаны использовать prefork MPM.

Если вы хотите получить больше производительности и стабильности с Apache, тогда вы можете взглянуть на ту же FPM систему, как в nginx и запустить worker MPM или event MPM, используя mod_fastcgi или mod_fcgid. Эта конфигурация позволит получить существенную экономию в памяти и будет намного быстрее, но потребует больше работы для установки.

Виртуальный хостинг

PHP, благодаря своей популярности, установлен на большом количестве виртуальных хостингов. Очень трудно найти хостинг без установленного PHP, но очень важно убедиться в том, что установлена последняя версия. Виртуальные хостинги позволяют вам и другим разработчикам развертывать веб-сайты на одной машине. Достоинством виртуального хостинга является его низкая цена. Недостатком — то, что вы не знаете, чем будут заниматься ваши соседи; сильно загружая сервер или открывая бреши в безопасности. Если бюджет вашего проекта позволяет избежать использования Виртуальных хостингов, то рассмотрите другие варианты.

Построение и развёртывание вашего приложения

Если вы обновляете структуру базы данных вручную или запускаете вручную тесты перед обновлением ваших файлов, то подумайте дважды! С каждой дополнительной необходимой ручной задачей для развёртывания новой версии вашего приложения, потенциальный шанс возникновения фатальной ошибки возрастает. Делаете ли вы простое обновление, полный процесс сборки или стратегию непрерывной интеграции автоматизация сборки — ваш друг.

Среди задач, которые вы, возможно, захотите автоматизировать:

  • Управление зависимостями
  • Компиляция, минификация файлов (assets)
  • Запуск тестов
  • Создание документации
  • Запаковка
  • Развёртывание

Создание инструментов автоматизации

Инструменты построения — коллекция скриптов, которые обрабатывают общие задачи развёртки приложений. Инструменты постройки не являются частью вашего приложения, они взаимодействуют с вашим приложением «извне».

Существует большое количество инструментов с открытым исходным кодом, которые могут помочь вам автоматизировать процесс постройки, некоторые написаны на PHP, другие на других языках. Это не должно удерживать вас от их использования, если они лучше подходят под задачу. Вот несколько примеров:

Phing самый простой путь, чтобы начать автоматическую развёртку в мире PHP. С Phing вы можете контролировать ваш процесс запаковки, развёртки или тестирования с помощью простого построечного XML файла. Phing (который базируется на Apache Ant) предоставляет богатый набор задач, часто необходимых для установки или обновления веб приложения, и может быть расширен дополнительными нестандартными задачами, написанными на PHP.

Capistrano — система для начинающих-профессиональных разработчиков для исполнения команд в структуризованном, воспроизводимом пути на одной или многих удалённых машинах. Предварительно он настроен для развёртки приложений Ruby on Rails. Как бы то ни было люди успешно развёртывают и PHP приложения с ним. Успех использования Capistrano зависит на умении работы с Ruby и Rake.

Сообщение в блоге Dave Gardner PHP Deployment with Capistrano является хорошей отправной точкой для PHP разработчиков, заинтересованных в Capistrano.

Chef является нечто большим, чем просто фрэймворк развёртки. Это очень мощный интеграционный фрэймворк, основанный на Ruby, который не просто развёртывает ваше приложение, но и может построить всё серверное окружение или виртуальный сервер.

Ресурсы о Chef для PHP разработчиков:

Для дальнейшего изучения:

Непрерывная интеграция

Непрерывная интеграция — это практика разработки программного обеспечения, при которой члены команды объединяют их работу очень часто, обычно каждый член команды объединяет как минимум ежедневно — что приводит к нескольким объединениям в день. Многие команды считают, что данный подход позволяет значительно сократить интеграционные проблемы и позволяет им разрабатывать совместный продукт быстрее.

Существуют разные пути, для осуществления непрерывной интеграции для PHP. Недавно Travis CI закончил великолепную работу по созданию непрерывной интеграции, реально даже для маленьких проектов. Travis CI — сервис непрерывной интеграции для сообщества с открытым исходным кодом. Оно интегрируется с GitHub и предлагает первоклассную поддержку для многих языков, включая PHP.

Для дальнейшего изучения:

Кэширование

PHP очень быстр сам по себе, но такие ресурсоёмкие операции, как установка удалённого подключения и, к примеру, загрузка файлов, могут привести к существенному падению скорости работы приложения. К счастью, есть различные инструменты, позволяющие поднять скорость определённых частей вашего приложения, или уменьшить количество запусков этих «тяжёлых» задач.

Кэширование байткода

Во время исполнения PHP файла, на низком уровне он сперва компилируется в байткод (или опкод) и только потом исполняется байткод. Если PHP файл не изменён, то байткод будет всегда одинаков. Это значит, что шаг компиляции — пустая трата процессорных ресурсов.

И тут настает время кэширования байткода. Оно предотвращает избыточные компиляции, сохраняя в памяти байткод и переиспользуя его в последовательных вызовах. Установка подобного кэширования — вопрос пары минут, а скорость вашего приложения поднимется существенно. Поэтому нет причин не использовать кэширование.

Начиная с PHP 5.5 появилось встроенное расширение для кэширования байткод — OPcache. Оно также доступно в виде отдельного расширения для ранних версий.

Популярные системы подобного кэширования:

  • APC (PHP 5.4 и более ранние)
  • XCache
  • Zend Optimizer+ (часть Zend Server)
  • WinCache (расширение для MS Windows Server)

Кэширование объектов

Бывают моменты, когда вам необходимо кэшировать определённые объекты в вашем коде, такие как данные, которые неразумно получать ещё раз из базы данных, когда результат вряд ли изменится. Вы можете использовать ПО для кэширования чтобы сохранить эти кусочки данных в памяти, что позволит чрезвычайно быстро обратиться к ним позже. Если вы сохраните эти объекты в хранилище данных и после получите их и выдадите напрямую из кэша для некоторых запросов, вы можете получить существенное улучшение производительности и уменьшение нагрузки на сервер базы данных.

Множество популярных решений для кэширования байткода также дают вам кэшировать данные, поэтому нет причин, чтобы не воспользоваться ими. APC, XCache и WinCache предоставляют API для сохранения данных из вашего PHP кода в свой кэш в памяти.

Самыми популярными системами кэширования объектов являются APC и memcached. APC — идеальный выбор для кэширования объектов, он включает простой API для добавления данных в кэш память и при этом очень просто устанавливается и используется. Единственное существующее ограничение APC состоит в том, что он привязан к серверу на котором установлен. Memcached, напротив, устанавливается как отдельный сервис, и к нему можно получить доступ по сети, что позволяет хранить объекты в очень быстром централизованном хранилище данных и множество других систем могут получать эти данные из него.

Учтите, если PHP запущен как (Fast-)CGI приложение внутри вашего веб-сервера, то каждый PHP процесс будет иметь собственный кэш, например, APC данные не будут расшарены между вашими процессами. В этом случае имеет смысл подумать об использовании вместо него memcached, так как он не ограничен процессом PHP.

В сетевой конфигурации APC зачастую выигрывает у memcached в плане скорости доступа, но memcached обладает возможностью масштабироваться быстрее и более широко. Если иметь несколько серверов для обслуживания приложения не входит в ваши планы или вам не нужны дополнительные возможности memcached, тогда APC будет лучшим выбором для кэширования объектов.

Пример использования APC:

Подробнее о популярных системах кэширования объектов:

Как включить IMAP функцию в PHP

По умолчанию модуль IMAP в PHP не установлен

1) Устанавливаем модуль PHP IMAP из менеджера пакетов

# apt-get install php5-imap

2) Задействуем функция IMAP

# php5enmod imap

3) перезагружаем сервис Apache

# service apache2 restart

Добавить комментарий Отменить ответ

Для отправки комментария вам необходимо авторизоваться.

Отправка писем php imap. Почтовые функции imap в РНР. Структура приложения и её кодировка

Одним из возможных применений imap функций является создание почтового демона, который будет управлять подпиской и отпиской пользователей от вашей почтовой рассылки. Для реализации этой задачи, обычно в рассылках используются два метода. Первый предполагает, что пользователь должен зайти на некую страницу и подтвердить свои действия, второй требует отправки письма. Второй так же требует, чтобы скрипт-обработчик регулярно запускался cron daemon?om. Из-за этого он не настолько популярен как первый способ.

Но, как можно заметить, наиболее серьезные рассылки используют второй способ. Поэтому, если у вас есть возможность использования crond, воспользуйтесь им.

Собственно, разобраться в функциях не так сложно. Человек, который раньше работал на РНР, без труда поймет, как с ними работать. Некоторые затруднения могут возникнуть с разбором заголовков писем, которые будет обрабатывать скрипт.

Алгоритм работы самого скрипта придумать несложно. Демон устанавливает соединение с почтовым сервером, и проверяет наличие на нем писем. В случае если писем нет, работа скрипта прекращается.
Если письма есть, то происходит разбор заголовков первого письма. Просматривается поля from и subject. Если поле subject содержит один из двух допустимых вариантов заголовка (подписка или отписка), то запись, которой соответствует значение поля from либо становится активной (подтвержденной), либо удаляется из таблицы. В обоих случаях на адрес, указанный в поле from посылается соответствующее извещение о действиях скрипта. После этого письмо помечается для удаления. В случае если subject не содержит допустимых тем, посылается уведомление об ошибке, и письмо так же помечается для удаления. Затем скрипт переходит к следующему письму.
Закончив разбор всех писем, он очищает ящик.

Не буду утомлять читателя блок-схемами, так что сразу перейдем к делу. Для открытия ящика используется функция imap_open. Поскольку РНР поддерживает работу с несколькими протоколами, то необходимо явно указать, какой протокол используется для работы с ящиком. В нашем случае это POP3 на 110 порту (стандарт). Присваиваем результат выполнения скрипта переменной $my_box.

В дальнейшем вы увидите, что эта переменная будет использоваться пратически во всех imap функциях. Далее проверяем ящик на наличие писем. Проверку выполняет функция imap_num_msg.

$n = imap_num_msg ($my_box );

В результате переменная $n будет содержать количество писем в ящике. Число это может быть или больше нуля, или равно ему (если ящик пуст).
Если письма есть, то в цикле while выполняем разбор писем, последовательно увеличивая номер письма на единицу. Обратите внимание, что первое письмо в ящике будет иметь номер 0, как, и первый элемент массива.
Для увеличения номера письма, присваиваем переменной $m значение 0, а потом в условиях выполнения цикла увеличиваем ее на единицу $m++.

Для разбора интересующих нас заголовков достаточно двух функций: imap_header и imap_fetch_overview. Для выполнения каждой из их, помимо ящика, нужно указывать номер письма. В нашем случае, внутри цикла он будет равен переменной $m.

Imap_header возвращает в результате выполнения объект, содержащий исчерпывающую информацию о заголовке письма. Среди всего прочего, этот объект содержит массив from, в котором содержаться четыре значения. Это personal, adl, mailbox и host. Нас из них интересуют только mailbox и host. Подставляя их, мы получим адрес, с которого было отправлено письмо.

$h = $h -> from ;
a
foreach ($h as $k => $v ) <
$mailbox = $v -> mailbox ;
$host = $v -> host ;
$personal = $v -> personal ;
$email = $mailbox . ? @ ¬ . $host ;

Imap_fetch_overview — позволит нам узнать тему письма. Для этих же целей можно было бы использовать и imap_header но по ряду причин это, иногда может не сработать. Из массива, который возвращает эта функция, нам нужно только поле subject

foreach ($s as $k => $v ) <
$subj = $v -> subject ;
>

Дальнейшие наши действия сводятся к тому, чтобы вытащить email из базы, и в случае наличия его там, пометить всю строку с этой записью как «проверенную», либо удалить. Предположим, что после заполнения формы рассылки на сайте, подписчику присваивается статус 0, а после подтверждения подписки он меняется на 1.

if ($subj == «SUBSCRIBE» ) <
mysql_query ( «UPDATE subscribe SET stat=1 WHERE email=$my_email» );

>
mysql_query ( «DELETE FROM subscribe WHERE email = $my_email» );
$del = imap_delete ($my_box , $m );
>
else <
$del = imap_delete ($my_box , $m );
>

как уже говорилось выше, после выполнения всех действий скрипт очищает ящик.

Данная простейшая программа, лишь демонстрация того, что на РНР можно писать не только динамически изменяющиеся сайты, но и сервисы, которые пользователю вообще не видны. Конечно, по части написания скриптов для shell, рнр неприменим, в отличие от своего конкурента Perl, но тем не менее…

Листинг всей программы за исключением параметров соединения с базой (db.php):

«From: Subscribe Robot

Content-type: text/plain; charset=UTF-8
» ;
if($n != 0 ) <
while($m ++ from ;
foreach ($h as $k => $v ) <
$mailbox = $v -> mailbox ;
$host = $v -> host ;
$personal = $v -> personal ;
$email = $mailbox . «@» . $host ;
$my_email = mysql_escape_string ($email );
>
foreach ($s as $k => $v ) <
$subj = $v -> subject ;
>
if ($subj == «SUBSCRIBE» ) <
mysql_query ( «UPDATE table SET stat=1 WHERE email=$my_email» );
//print mysql_error();
$del = imap_delete ($my_box , $m );
mail ($email , $add_sbj , $add_text , $headers );
>
elseif ($subj == «UNSUBSCRIBE» ) <
mysql_query ( «DELETE FROM table WHERE email = $my_email» );
$del = imap_delete ($my_box , $m );
mail ($email , $del_sbj , $del_text , $headers );
>
else <
$del = imap_delete ($open_box , $m );
mail ($email , $err_sbj , $err_text , $headers );
>
>
$clear = imap_expunge ($my_box );
>
?>

Одним из возможных применений imap функций является создание почтового демона, который будет управлять подпиской и отпиской пользователей от вашей почтовой рассылки. Для реализации этой задачи, обычно в рассылках используются два метода. Первый предполагает, что пользователь должен зайти на некую страницу и подтвердить свои действия, второй требует отправки письма. Второй так же требует, чтобы скрипт-обработчик регулярно запускался cron daemon-om. Из-за этого он не настолько популярен как первый способ.

Но, как можно заметить, наиболее серьезные рассылки используют второй способ. Поэтому, если у вас есть возможность использования cron, воспользуйтесь им.

Собственно, разобраться в функциях не сложно. Некоторые затруднения могут возникнуть с разбором заголовков писем, которые будет обрабатывать скрипт.

Алгоритм работы самого скрипта придумать несложно. Демон устанавливает соединение с почтовым сервером, и проверяет наличие на нем писем. В случае если писем нет, работа скрипта прекращается. Если письма есть, то происходит разбор заголовков первого письма. Просматривается поля from и subject. Если поле subject содержит один из двух допустимых вариантов заголовка (подписка или отписка), то запись, которой соответствует значение поля from либо становится активной (подтвержденной), либо удаляется из таблицы. В обоих случаях на адрес, указанный в поле from посылается соответствующее извещение о действиях скрипта. После этого письмо помечается для удаления. В случае если subject не содержит допустимых тем, посылается уведомление об ошибке, и письмо так же помечается для удаления. Затем скрипт переходит к следующему письму. Закончив разбор всех писем, он очищает ящик.

Для открытия ящика используется функция imap_open . Поскольку PHP поддерживает работу с несколькими протоколами, то необходимо явно указать, какой протокол используется для работы с ящиком. В нашем случае это pop3 на 110 порту (стандарт). Присваиваем результат выполнения скрипта переменной $my_box.

В дальнейшем вы увидите, что эта переменная будет использоваться пратически во всех imap функциях. Далее проверяем ящик на наличие писем. Проверку выполняет функция imap_num_msg.

В результате переменная $n будет содержать количество писем в ящике. Число это может быть или больше нуля, или равно ему (если ящик пуст). Если письма есть, то в цикле while выполняем разбор писем, последовательно увеличивая номер письма на единицу. Обратите внимание, что первое письмо в ящике будет иметь номер 0, как, и первый элемент массива. Для увеличения номера письма, присваиваем переменной $m значение 0, а потом в условиях выполнения цикла увеличиваем ее на единицу $m++.

Илон Маск рекомендует:  Тег var

Для разбора интересующих нас заголовков достаточно двух функций: imap_header и imap_fetch_overview . Для выполнения каждой из их, помимо ящика, нужно указывать номер письма. В нашем случае, внутри цикла он будет равен переменной $m.

imap_header возвращает в результате выполнения объект, содержащий исчерпывающую информацию о заголовке письма. Среди всего прочего, этот объект содержит массив from, в котором содержаться четыре значения. Это personal, adl, mailbox и host. Нас из них интересуют только mailbox и host. Подставляя их, мы получим адрес, с которого было отправлено письмо.

$h = imap_header($my_box, $m); $h = $h->from; foreach ($h as $k => $v) < $mailbox = $v->mailbox; $host = $v->host; $personal = $v->personal; $email = $mailbox . «@» . $host;

imap_fetch_overview — позволит нам узнать тему письма. Для этих же целей можно было бы использовать и imap_header но по ряду причин это, иногда может не сработать. Из массива, который возвращает эта функция, нам нужно только поле subject

$s = imap_fetch_overview($my_box, $m); foreach ($s as $k => $v) $subj = $v->subject;

Дальнейшие наши действия сводятся к тому, чтобы вытащить email из базы, и в случае наличия его там, пометить всю строку с этой записью как, либо удалить. Предположим, что после заполнения формы рассылки на сайте, подписчику присваивается статус 0, а после подтверждения подписки он меняется на 1.

Данная простейшая программа, лишь демонстрация того, что на PHP можно писать не только динамически изменяющиеся сайты, но и сервисы, которые пользователю вообще не видны.

Листинг всей программы за исключением параметров соединения с базой:

Include «config.php»; // соединение с БД $my_box = imap_open(««, «login», «password»); $n = imap_num_msg($my_box); $m = 0; $add_text = » Спасибо за подтверждение вашей подписки «; $add_sbj = «you added!»; $del_text = » Вы были удалены из списка рассылки. «; $del_sbj = «delete from list»; $err_text = » Извините но этот почтовый ящик используется только для администрирования рассылки»; $err_sbj = «error»; $headers = «from: subscribe robot x-mailer: php4 content-type: text/plain; charset=windows-1251 «; if($n != 0) < while($m++ from; foreach ($h as $k =>$v) < $mailbox = $v->mailbox; $host = $v->host; $personal = $v->personal; $email = $mailbox . «@» . $host; $my_email = mysql_escape_string($email); > foreach ($s as $k =>$v) $subj = $v->subject; if ($subj == «subscribe») < mysql_query("update table set stat=1 where email=$my_email"); //print mysql_error(); $del = imap_delete($my_box, $m); mail($email, $add_sbj, $add_text, $headers); >else if ($subj == «unsubscribe») < mysql_query("delete from table where email = $my_email"); $del = imap_delete($my_box, $m); mail($email, $del_sbj, $del_text, $headers); >else < $del = imap_delete($open_box, $m); mail($email, $err_sbj, $err_text, $headers); >> $clear = imap_expunge($my_box); >

В листингe отсутствуют некоторые детали, например возможное конвертирование из win в koi, перепроверка почтового ящика отправителя и т.д. Это уже функциональные излишества, которые каждый может добавить по мере необходимости.

На днях мне пришло задание написать небольшой модуль на PHP, который бы позволил работать с входящей почтой. Немного по гуглив я увидел что для данного задания мне подходит один из протоколов POP3 и IMAP .
Но выбор был очевиден что использовать я буду IMAP так как он более функциональный и современней, протокола POP3.

Теперь мне надо было быстренько разобраться как работать с протоколам IMAP , как получить письма из почтового сервера Yandex/Google.

Для более удобной работы я выбрал библиотеку PhpImap , так как она может быстро и легко реализует все нужные для меня задачи.

Подключение к почтовому серверу.

Теперь когда мы определились с выбором протокола и выбором библиотеки, будем пробовать подключатся к почтовому серверу.

Для полноценной работы PHP с протоколом IMAP, необходимо подключить расширение php_imap.dll/imap.so в файле php.ini.

Для начало попробуем подключится к Yandex почте так как у меня меньше всего возникло с ней проблем.

//Подключаем библиотеки include(«/phpImap/Mailbox.php»); include(«/phpImap/IncomingMail.php»); //Для удобства создам константы для подключения к почтовому серверу. define(«MAIL_IMAP_SERVER», «imap.yandex.ru»); define(«MAIL_IMAP_SERVER_PORT», 993); define(«MAIL_IMAP_LOGIN», » «); define(«MAIL_IMAP_PASS», «example_pass»); define(«MAIL_IMAP_PATH», «<".MAIL_IMAP_SERVER.":".MAIL_IMAP_SERVER_PORT."/imap/ssl>INBOX»); $mailbox = new PhpImap\Mailbox(MAIL_IMAP_PATH, MAIL_IMAP_LOGIN, MAIL_IMAP_PASS, __DIR__); try < $mailbox->getImapStream(); > catch (Exception $e) < die($e->getMessage()); >

Как мы видим конструктор класса Mailbox принимает следующие аргументы:

  • MAIL_IMAP_PATH — Cодержит в себе адрес сервера (MAIL_IMAP_SERVER), порт подключения (MAIL_IMAP_SERVER_PORT), тип соединения (imap) и показываем что соединение будет зашифровано (ssl). После фигурных скобок указываем папку к которой будем подключаться, в данном случае к входящим сообщениям (INBOX).
  • MAIL_IMAP_LOGIN — Почтовый ящик которому будем подключатся.
  • MAIL_IMAP_PASS — Пароль (чаще всего это пароль от почтового ящика).
  • __DIR__ — Это путь к папке в которой будут сохраняться вложенные файлы и почтовые сообщения.

После этого мы проверим, создалось ли наше подключение через метод getImapStream() если по какой-то причине подключения не создастся то приложение выбрасывает исключения с причиной не удачного подключения.

Важно учесть во внимание то что в настройках Yandex почты у вас может быть отключена возможность подключения по протоколу IMAP.

Теперь давайте сравним подключение к почте Gmail.

Define(«MAIL_IMAP_SERVER», «imap.gmail.com»); define(«MAIL_IMAP_SERVER_PORT», 993); define(«MAIL_IMAP_LOGIN», » «); define(«MAIL_IMAP_PASS», «example_pass»); define(«MAIL_IMAP_PATH», «<".MAIL_IMAP_SERVER.":".MAIL_IMAP_SERVER_PORT."/imap/ssl>INBOX»);

Как мы видим оно практически не отличается от предыдущего подключения, но скорей всего у Вас сработает исключение при подключении к серверу.
Это проблема связана с тем что в Gmail работа протокола IMAP отключена по умолчанию . Включить её можно в настройках во вкладке Пересылка и POP/IMAP в опции Доступ по протоколу IMAP ⇒ Включить IMAP.

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

Учтите что при создании пароля приложений у Вас может быть так и не получится подключиться к серверу это связно с тем что данный пароль еще не применялся окончательно к сервису Gmail обычно это занимает 5-60 минут.

Выборка данных

После успешного подключения, мы можем выполнить запрос для получения потовых сообщений из сервера. Для этого мы будем использовать метод searchMailBox(string $criteria) который по сути является оберткой метода imap_search . Тут важно понять что аргумент $criteria является неким критерием поиска нужных нам сообщений, сам метод возвращает идентификаторы элементов которые в последствии нам пригодятся для получения детальной информации почтового сообщения.

Как Вы уже догадались тут мы получаем все сообщения.
А теперь давайте попробуем разобраться и с другими не менее важными критериями поиска:

//Все сообщения за 3 дня. $mails >searchMailBox(«SINCE «».date(«d-M-Y»,strtotime(«-3 day»)).»»»); //Непрочитанные сообщения за 3 дня. $mails >searchMailBox(«UNSEEN SINCE «».date(«d-M-Y»,strtotime(«-3 day»)).»»»); //Поиск сообщений с таким соответствием в заголовке TEXT. $mails >searchMailBox(«TEXT «Новостная рассылка»»); //Поиск сообщений с таким соответствием в заголовке BODY. $mails >searchMailBox(«BODY «Информационное сообщение»»); //Поиск по емейлу отправителя. $mails >searchMailBox(«FROM » «»); //Получить сообщения по заголовку SUBJECT $mails >searchMailBox(«SUBJECT «Выпущены обновления для вашего телефона»»);

Данный пример хорошо отражает основы использование критериев поиска.

Получение информации

Теперь когда у нас есть массив идентификаторов сообщений мы готовы его обработать:

//Получаем идентификатор последнего сообщения из массива. $ >getMail($id); //Получаем файлы вложенные к данному сообщению если он есть. $mail->getAttachments(); //Выводим сообщения. echo $mail->textHtml;

Вот мы и получили сообщения из нашего письма и его вложения без всяких заморочек.

Дополнительные возможности.

В данной библиотеке также присутствие ряд полезных методов для более удобной работы с почтовыми сообщениями:

Сохраняем сообщения по его ид.

Устанавливаем сообщения как непрочитанное по его id.

Устанавливаем сообщения как прочитанное по его id.

Устанавливаем на сообщение пометку по его id.

Удаляем сообщения по его id.

Электронная почта – это важнейший инструмент для обмена информацией и если вы её используете для работы, то наверняка сталкивались с ситуацией: на почту приходит письмо, в котором содержатся данные необходимые для обработки скрипом. Говорить мы будем о Яндекс почте – в этой статье я поделюсь с вами, дорогие читатели, опытом как достать письма из ящика, так же мы разберем вариант, когда в письме есть вложенный файл — как его обнаружить и в итоге скачать для дальнейших манипуляций над ним.

Сам я с этой задачей столкнулся достаточно давно, и тогда при наличии малого опыта работы c почтовыми программами Яндекса потратил массу времени и нервов для достижения требуемого результата. Первая моя ошибка заключалась в том, что, как многие веб-разработчики, я начел интенсивно искать похожие примеры в сети, но не воспользовался самой справкой (помощью) Яндекс. Да, там есть полезная информация, хотя её и очень мало, но она достаточно важная для написания такого рода скрипта (об этом будет ниже). На то время требовалось написать скрипт, суть которого сводилось: на Яндекс почту заказчика приходило письмо с прайсом товаров в xls формате раз в сутки, его необходимо было обработать (распарсить и сравнить с данными из БД интернет магазина и, в зависимости от результата, что-то обновить где-то, отключить или включить).

И первое, что мы сделаем перед написанием скрипта – это наметим наш план действий, который будет состоять из девяти пунктов:

  1. Настроим почту для получения доступа через почтовые протоколы;
  2. Наметим саму структуру PHP приложения и определимся с кодировкой файлов;
  3. Познакомимся с почтовым протоколом IMAP и его возможностями;
  4. Подключимся к Яндекс почте через логин и пароль аккаунта и отследим ошибки на этом этапе;
  5. Обработаем шапку письма;
  6. Получим и обработаем тела письма;
  7. Получим и сохраним вложенные файлы;
  8. Визуализируем проделанную работу;
  9. Сделаем выводы.

Тема довольно объёмная, но я постараюсь изложить всё максимально компактно и понятно. Пожалуй, приступим.

Настройка почты

Переходим в свою почту и заходим в настройки, как показано ниже на скриншоте:

Теперь мы попали в настройки работы почты через протоколы IMAP и POP3:

Тут многие увидят картину как на изображение выше, но я сталкивался, и не один раз, когда доступы отключены. Поэтому если у вас настройки другие, ставим галочки как на скриншоте, для нас главное разрешить доступ через протокол IMAP.

Структура приложения и её кодировка

В этом примере мы не будем придумывать сложную структуру приложения, так как она не нужна, а добавим только то, что необходимо (я работаю в редакторе Sublime Text):

  • tmp – папка в которую будем загружать вложенные файлы из письма, если они есть;
  • .htaccess – настройка серверной части, если у вас сервер apache;
  • functions.php – сюда будем добавлять наши функции;
  • main.css – файл стилей;
  • index.php – точка входа приложения;

Кодировку будем использовать UTF-8 и поэтому сразу заполним файл.htaccess следующими строками:

AddDefaultCharset utf-8 AddCharset utf-8 * CharsetSourceEnc utf-8 CharsetDefault utf-8

Протокол IMAP

Возвращаясь к первому пункту видно, что работать с почтой Яндекс можно также и через протокол POP3. Так почему же именно IMAP? Из двух этих протоков IMAP является более новым и альтернативным POP3, следовательно, у него есть ряд преимуществ (их можно изучить, воспользовавшись википедией), но в нашем случае на выбор повлияло только то, что он более новый. Лично я особой разницы не вижу, что использовать под конкретную задачу получения письма. Если по какой либо причине вам потребуется использовать протокол POP3 то все функции, которые применимы к IMAP будут работать и для него.

Подключаемся к Яндекс почте при помощи протокола IMAP

Для того чтобы подключиться к почте нам нужно знать три параметра: логин почты, её пароль и адрес почтового сервера. Если с двумя параметрами проблем нет, то второй можно найти именно в помощи Яндекс. Об этом (возникшей у меня проблеме) я выше и писал в сети масса примеров, где третий параметр указан не правильно и, представьте себе, что уже на стадии подключения возникают ошибки – это, как минимум, неприятно. Я не буду ходить вокруг да около и сразу дам прямую ссылку на страницу Яндекс – настройка почтовых программ . Вот собственно что нам нужно для подключения:

Теперь можно переходить непосредственно к самому коду:

Header(«Content-Type: text/html; charset=utf-8»); error_reporting(0); require_once(«functions.php»); $mail_login = «yandex_почта»; $mail_password = «пароль_от_почты»; $mail_imap = ««; // Список учитываемых типов файлов $mail_filetypes = array(«MSWORD»); $connection = imap_open($mail_imap, $mail_login, $mail_password); if(!$connection)< echo("Ошибка соединения с почтой - ".$mail_login); exit; >else< $msg_num = imap_num_msg($connection); $mails_data = array(); for($i = 1; $i MailDate); $mails_data[$i]["date"] = $msg_header->MailDate; foreach($msg_header->to as $data)< $mails_data[$i]["to"] = $data->mailbox.»@».$data->host; > foreach($msg_header->from as $data)< $mails_data[$i]["from"] = $data->mailbox.»@».$data->host; >

Сохраняем в нашем массиве: временную метку, дату получения письма, email получателя и отправителя и переходим к получению темы письма. Для этого нам необходимо вначале добавить три функции в файл functions.php:

Названия говорящие и, я думаю, стоит пояснить только последнюю функцию. Она принимает закодированную строку и при помощи imap_mime_header_decode() декодирует ее, в результате чего возвращается массив объектов, у каждого из которых есть два свойства charset (кодировка) и text (текст темы). Дальше всё просто: в цикле проверяя кодировку, приводим к UTF-8 и склеиваем тему в единый заголовок и возвращаем его.

Теперь вернёмся в файл index.php и вытянем последний параметр:

На этом обработка шапки письма будет завершена.

Работаем с телом письма

Продолжаем постепенно формировать наш массив с обработанными данными письма и теперь для получения тела нам необходимо воспользоваться двумя функциями:

// Тело письма $msg_structure = imap_fetchstructure($connection, $i); $msg_body = imap_fetchbody($connection, $i, 1);

В первой переменной $msg_structure находится структура письма – это объект, в котором можно найти массу полезной информации, пример части этого объекта представлен ниже:

Что важно для решения нашей задачи:

  • type – первичный тип тела письма, в зависимости от того, что к нам приходит на почту он может меняться от 0 до 7 (каждой цифре советует свой вид контента который находиться в теле письма);
  • encoding – кодировка трансфера тела, меняется от 0 до 5 (0 — 7BIT, 1 — 8BIT, 2 – BINARY, 3 — BASE64, 4 — QUOTED-PRINTABLE, 5 — OTHER);
  • parts – массив частей письма, который соответствует структуре объекта уровнем выше.

Немного подробнее рассмотрим свойство parts. Первое, что нужно сказать это то, что в нулевой ячейке этого массива находиться информация, соответствующая именно тексту письма, а начиная с первого – вложенным файлам. Также в каждом объекте указывается type и в parameters кодировка в явном и в не явном виде.

Структура письма может быть сколько угодно вложенной, по крайне мере у меня были случаи, когда доходило до четырёх — пяти уровней, поэтому чтобы её, как говорится, раздраконить нам в дальнейшем потребуется написать рекурсивную функцию.

Вторая функция imap_fetchbody() извлекает определённую часть письма, чаще всего в закодированном виде.

Теперь добавим переменную, в которую будем сохранять обработанную версию тела письма:

Вернёмся в файл functions.php и напишем рекурсивную функцию:

Function recursive_search($structure)< $encoding = ""; if($structure->subtype == «HTML» || $structure->type == 0)< if($structure->parameters->attribute == «charset»)< $charset = $structure->parameters->value; > return array(«encoding» => $structure->encoding, «charset» => strtolower($charset), «subtype» => $structure->subtype); >else< if(isset($structure->parts))< return recursive_search($structure->parts); >else< if($structure->parameters->attribute == «charset»)< $charset = $structure->parameters->value; > return array(«encoding» => $structure->encoding, «charset» => strtolower($charset), «subtype» => $structure->subtype); > > >

Функция recursive_search() принимает один параметр – структуру письма, где последовательно проверяет свойства и достает три параметра: encoding, charset, subtype. Точкой выхода из рекурсии является отсутствие свойства parts с нулевой ячейкой. Больше пояснять тут особо нечего, из кода я думаю понятно, что и как происходит.

Добавим ещё одну функцию для переконвертации тела письма, которая нам потребуется в дальнейшем:

После того, как мы получили данные из рекурсии, постепенно проверяем кодировку трансфера и, в зависимости от этого, вызываем функцию structure_encoding() с соответствующими параметрами. В последнем условном операторе учитываем, то, что мы работает в UTF-8 и если после всех манипуляций у нас получится отличное от кодировки, перекодируем.

Осталось подвести черту:

В теле письма может оказаться, как и обычный текст, так и HTML разметка со своими стилями. Кодируем в BASE64, чтобы при визуализации не поехала уже наша верстка.

Вложенные файлы

Вот, плавно подбираемся к концу написания нашего приложения:

// Вложенные файлы if(isset($msg_structure->parts))< for($j = 1, $f = 2; $j parts); $j++, $f++)< if(in_array($msg_structure->parts[$j]->subtype, $mail_filetypes))< $mails_data[$i]["attachs"][$j]["type"] = $msg_structure->parts[$j]->subtype; $mails_data[$i][«attachs»][$j][«size»] = $msg_structure->parts[$j]->bytes; $mails_data[$i][«attachs»][$j][«name»] = get_imap_title($msg_structure->parts[$j]->parameters->value); $mails_data[$i][«attachs»][$j][«file»] = structure_encoding($msg_structure->parts[$j]->encoding, imap_fetchbody($connection, $i, $f)); file_put_contents(«tmp/».iconv(«utf-8», «cp1251», $mails_data[$i][«attachs»][$j][«name»]), $mails_data[$i][«attachs»][$j][«file»]); > > >

Кусок, отвечающий за обработку вложенного файла гораздо меньше, а теперь — почему именно так. Принцип работы с файлом аналогичен работе с телом письма, только этот этап начинаем с наличия его в массиве свойства parts. Не забываем отсеивать ненужные, сверяясь со списком типов. При помощи нехитрой функции file_put_contents() мы сохраняем наш файл к себе на сервер в папку tmp.

Хочу увидеть результат!

В процессе работы у нас сформировался массив с данными $mails_data, и для визуализации мы уже будем работать непосредственно с ним. В этой статье я использовал тестовое письмо, которое лежало у меня почте, давайте глянем, что у нас получилось в итоге:

Вот какого вида примерно должен у вас получиться массив, увы, пришлось скрыть содержание файла по личным причинам. Теперь переходим к нашей HTML разметке:

PHP: использование программ на языке PHP

Пользователям хостинга предоставляется возможность использовать на своих сайтах программы на языке PHP (в соответствии с тарифным планом). У нас установлена одна из последних версий PHP и мы стараемся по мере возможности ее обновлять. Текущую конфигурацию можно посмотреть при помощи функции phpinfo().

Пример скрипта для просмотра конфигурации PHP:

Что такое PHP и как начать с ним работать

PHP: Hypertext Preprocessor — очень простой даже для начинающего веб-программиста язык, который, тем не менее, обладает очень серьезными возможностями. PHP — язык достаточно высокого уровня, что позволяет просто реализовывать на нем именно веб-проекты, не заботясь при этом о ненужных низкоуровневых процессах. Если Вы хотите добавить динамику и интерактив на свой сайт, но при этом не хотите изучать более сложные языки вроде Perl, можно использовать PHP. Этот язык также содержит большое количество встроенных возможностей для работы с популярной СУБД MySQL, что делает выбор PHP для веб-программирования еще более привлекательным.

Начать использовать PHP очень просто: нужно создать в веб-пространстве файл с расширением *.php и поместить в него нужные PHP-инструкции . Например, создадим файл test.php в каталоге www вашего домена и поместим в него следующий текст:

Теперь откройте страницу http://www.ваш_домен.ru/test.php и Вы увидите результат выполнения скрипта. PHP — это просто. Простоты этому языку добавляет наличие отличной документации на русском языке, которая доступна здесь . Есть отличный поиск по документации, примеры использования функций, а также прямо на сайте Вы можете почитать рекомендации пользователей PHP по применению конкретных возможностей.

Поддерживаемые на нашем хостинге функции

Мы используем одну из последних версий PHP в виде модуля для веб-сервера Apache, которая собрана с поддержкой следующих модулей (функций):

Расширения файлов для PHP-скриптов, как добавить свое расширение

Интерпретатором PHP автоматически обрабатываются как PHP-сценарии файлы со следующими расширениями:

То есть, файлы, имеющие такие расширения, будут автоматически обрабатываться веб-сервером как PHP-скрипты . Например, index.php или 123.phtml. Пользователь может самостоятельно добавить собственные расширения для обработки соответствующих файлов как PHP-сценариев , поместив в файл .htaccess строку вида:

где ext1, php3 и .html — добавляемые расширения в названии файлов. Например, в данном случае PHP-скриптами будут считаться файлы index.ext1, file.php3 и test.html.

Отправка писем с вложениями при помощи функции mail

Ссылки на готовые примеры скриптов, использующих функцию mail для отправки писем с вложениями, есть в документации на сайте разработчика: LII. Mail Functions .

Авторизованная отправка писем с серверов виртуального UNIX-хостинга

В целях безопасности, на всех серверах виртуального UNIX-хостинга заблокированы исходящие соединения на 25 порт и 587, поэтому необходимо использовать альтернативный номер порта, который нужно уточнить у владельца SMTP-сервера. Если отправка будет осуществляться через наш SMTP-сервер, используйте порт 2525.

Пример авторизованной отправки почты с использованием smtp-сервера.

Скачать пример готового скрипта с функцией MailSmtp(): smtpauth.php.sample

Использовать описанную выше функцию MailSmtp() можно для прямой замены функции mail(). Рассмотрим пример самой простой формы на PHP:

Для того, что бы данная форма заработала без функции mail() мы включили файл smtpauth.php через require_once и вызвали функцию MailSmtp(), описанную в нем, с аналогичными для mail() аргументами. При этом сам вызов mail() мы закомментировали в коде, что бы избежать ошибки при выполнении скрипта.

Отправка писем при помощи функции mail()

В следующим примере мы воспользуемся встроенной функцией mail(), где в качестве параметров, клиентские данные будут переданы посредством $_POST запроса.

Проблемы работы функций strtoupper() и strtolower() с кириллицей

Проблемы при работе с кириллицей в PHP-скриптах функций strtoupper() и strtolower() возникают, когда неправильно определена текущая локаль (locale). Для правильного её определения следует воспользоваться функцией setlocale() в самом начале вашего PHP-сценария:

Поиск с помощью Яндекс.XML

Если Вы решили воспользоваться сервисом Яндекс.XML , то прежде всего вам потребуется выделенный IP-адрес , который Вы можете добавить для любого домена в личном кабинете: в меню Древо услуг > Домен, напротив характеристики «выделенный IP/SSL» нажмите «добавить» (в данном случае подключать SSL не обязательно, но в комментариях обязательно укажите причину, по которой вам понадобился выделенный IP-адрес ).

Далее для организации запроса именно с выделенного IP-адреса существует несколько вариантов:

Здесь переменная $search обозначает только сам поисковый запрос, как это описано на сайте Яндекса, то, что написано после выражения «query=».

Переменная $search — HTTP-запрос целиком (то есть URL).

Как измененить версию PHP

Для изменения версии PHP пройдите в личный кабинет https://cp.masterhost.ru, нажмите на пункт меню «Древо услуг» и выберите вашу виртуальную площадку uXXXXX. Далее в списке параметров найдите строчку смена версии ПО и нажмите кнопку изменить, как показано на рисунке.

Если необходимо изменить версию PHP только для одного домена, то необходимо в «Древе услуг» выбрать домен, далее PHP и нажать кнопку изменить, как на рисунке:

Затем в выпадающем списке выбрать нужную версию PHP.

Как увеличить лимиты: потребление оперативной памяти (memory_limit), время выполнения скрипта (max_execution_time) и т.п.

Лимиты потребления PHP-интерпретатором ресурсов сервера (memory_limit, max_execution_time и т.п.) регулируются тарифным планом площадки виртуального хостинга. Чтобы увеличить такие лимиты, необходимо перейти на следующий по старшинству тарифный план. Ознакомиться с техническими параметрами Вашего тарифного плана можно в Приложении №1.1 к Публичной оферте (Договору), а также на странице с выводом функции phpinfo(), ссылка на которую доступна на странице с характеристиками тарифного плана.

Как собрать свой собственный интерпретатор PHP или внести изменения на уровне компиляции PHP (добавление модулей, изменение системных опций PHP_INI_SYSTEM)

На серверах виртуального хостинга недоступен Си-компилятор, поэтому сборка из исходных кодов собственного PHP-интерпретатора невозможна. Если для работы Вашего проекта требуется нестандартная конфигурация PHP или наличие библиотек, которые отсутствуют в нашей сборке, мы рекомендуем рассмотреть наши услуги по аренде виртуального (VPS) или физического (dedicated) сервера без нашего администрирования. Такой сервер не будет зависеть от конфигурации и ограничений нашей хостинговой среды, и Вы, как администратор сервера, сможете самостоятельно установить и настроить любое необходимое Вашему проекту программное обеспечение.

Также о возможности установки нестандартного ПО на Вашей площадке Вы можете уточнить у наших инженеров службы технической поддержки, отправив письменную заявку «на свободную тему» из Личного кабинета. Возможно, предоставление этого ПО на площадках виртуального хостинга уже находится в наших ближайших планах, или мы сможем установить его для Вас на dediacated сервер с нашим администрированием.

Как изменить значение опций, имеющих статус изменяемости PHP_INI_PERDIR или PHP_INI_ALL

Вы можете изменить некоторые директивны PHP непосредственно в личном кабинете. Для этого перейдите в раздел «Древо услуг» и нажмите на Вашем сайте, для которого нужно изменить настройки PHP. На странице с параметрами размещенного сайта найдите строчку PHP и нажмите изменить, как показано на рисунке.

На открывшейся странице Вам будет доступен интерфейс управления некоторыми настройками PHP-интерпретатора

Если нужной директивы со статусом изменяемости PHP_INI_PERDIR или PHP_INI_ALL нет в списке, Вы можете изменить ее с помощью управляющего файла .htaccess

В следующем примере мы изменим значение директивы mail.log , которая в качестве параметра принимает путь до файла, в который будут записываться все вызовы функции mail() при отправке писем скриптами сайта. Для этого воспользуемся файлом .htaccess, в который нужно добавить всего одну строчку.

Теперь все вызовы функции mail() скриптами этого сайта будут записываться в файл phpmail.log в корне площадки u12345. Аналогичным образом можно менять и другие директивы, если их статус изменяемости соответствует PHP_INI_PERDIR или PHP_INI_ALL.

Напомним значение и расшифровку констант PHP_INI_*:

PHP_INI_USER 1 Опция может быть установлена в пользовательских скриптах
PHP_INI_PERDIR 2 Опция может быть установлена в php.ini , .htaccess или httpd.conf
PHP_INI_SYSTEM 4 Опция может быть установлена в php.ini или httpd.conf
PHP_INI_ALL 7 Опция может быть установлена где угодно

Список, описание и статус изменяемости директив можно найти в приложении G документации PHP.

Как выполнять PHP-скрипты в заданное время по расписанию

Иногда у PHP-программистов возникают задачи, которые требуют запуска PHP-скриптов в указанное время. Например, загрузка прайс-листа в базу данных, создание/удаление файлов на диске сервера, загрузка на сервер документов с других серверов и так далее. Можно использовать для этого возможности программы cron, которая работает на сервере.

Подробности о работе cron и его использовании Вы найдете в отдельном документе. Здесь же мы опишем тонкости запуска таким образом именно PHP-скриптов .

На наших серверах установлен бинарный файл интерпретатора PHP, который можно вызывать из cron. Полный путь к нему — /usr/local/bin/php. В качестве параметра нужно передать полный путь до запускаемого PHP-скрипта . Пример задания для cron:

в случае с PHP 5

или в случае с PHP 4

В данном примере скрипт, который находится на диске сервера и имеет полный путь /home/uXXXXX/script.php, запускается в 1 час ночи каждый день. Не забывайте нажимать Enter после каждой строки в cron — все строки в сценариях cron должны заканчиваться переводом строки или задание работать не будет.

Вывод ошибок в PHP

Иногда возникает необходимость получить информацию о том, какие ошибки возникают при выполнении PHP-скриптов. При использовании PHP как модуля Apache (по умолчанию именно так) вывод ошибок доступен в личном кабинете в меню Древо услуг в разделе Домен domain.tld, где domain.tld — имя вашего домена, далее характеристика HTTP > error_log.

Иногда имеет смысл включить вывод ошибок PHP-скриптов на экран. Возможно 2 случая:

Если Вы используйте PHP-интерпретатор как модуль Apache, создайте в той директории, где находятся скрипты, файл .htaccess (если он не существует) и добавьте 2 строки, одна из которых включает вывод ошибок в браузер, а вторая определяет уровень отображаемых ошибок:

Число 2047 является значением константы E_ALL и включает вывод всех типов ошибок. Значение константы E_ALL зависит от версии PHP. Точное значение можно узнать на сайте разработчика .

Если Вы используете PHP-интерпретатор как CGI, то для вывода ошибок следует в файле настроек для PHP, изменить значение параметра

Кроме этого, надо изменить значение параметра error_reporting со значения E_ALL & E_NOTICE на простое E_ALL (по желанию).

Ошибки при выполнении PHP-скриптов могут быть разного типа. Полный список констант, определяющих тип отображаемых ошибок, может быть найден на сайте разработчика

Ограничения

Нужно учитывать, что на работу PHP налагаются некоторые ограничения. По соображениям безопасности мы запретили использование следующих команд:

  • dl
  • shell_exec
  • exec
  • system
  • passthru
  • popen
  • proc_open
  • proc_nice
  • proc_get_status
  • proc_close
  • proc_terminate
  • posix_mkfifo
  • set_time_limit
  • chown
  • chgrp
  • accelerator_reset
  • opcache_reset
  • accelerator_get_status
  • opcache_get_status
  • pcntl_alarm
  • pcntl_fork
  • pcntl_waitpid
  • pcntl_wait
  • pcntl_wifexited
  • pcntl_wifstopped
  • pcntl_wifsignaled
  • pcntl_wexitstatus
  • pcntl_wtermsig
  • pcntl_wstopsig
  • pcntl_signal
  • pcntl_signal_dispatch
  • pcntl_get_last_error
  • pcntl_strerror
  • pcntl_sigprocmask
  • pcntl_sigwaitinfo
  • pcntl_sigtimedwait
  • pcntl_exec
  • pcntl_getpriority
  • pcntl_setpriority

Если на самом деле Вы хотите использовать функции вроде exec для выполнения периодических заданий вроде бэкапа баз MySQL, пожалуйста, используйте для этого cron. Если же нужно разово выполнить какую-то команду, можно использовать для этого UNIX shell.

Документация и полезные ссылки

В помощь вам мы приводим ссылки на полезные ресурсы по тематике PHP:

  • Руководство по PHP — полная документация на русском языке с возможностью поиска
  • Клуб разработчиков PHP — на русском языке
  • Подборка статей по PHP — сервер CIT Forum
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL