3.3K

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

Очень часто создание и вывод сообщений разнесены по разным HTTP-запросам. Как правило, удобно бывает использовать редирект после обработки форм (чтобы избежать проблем с кнопками Back и Refresh), но в то же время естественный момент для создания сообщения - это именно момент обработки форм и совершения действий, ему сопутствующих. Почему? Представьте, что текст сообщения должен выглядеть примерно так: "Количество заказываемых единиц товара ‘Коврик для мыши’ успешно изменено с 7 до 12". После редиректа, возможно, на совершенно другую с точки зрения функциональности страницу, это будет лишняя головная - определить, что же было совершено до этого.

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

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

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

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

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

Идея очень простая, и ее можно реализовать с помощью пары классов.

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

class Message { /** * Содержание сообщения. */ var $content; /** * Конструктор для инициализации текста сообщения. * * @param content содержание сообщения */ function Message($content) { $this->content = $content; } /** * Запись сообщения в сессию. */ function send() { $_SESSION["session_messages"] = $this->content; } /** * Вывод сообщения на страницу. */ function toPage() { echo " - " . $this->content . "
"; } }

Для доступа к сессии используется переменная $_SESSION.

Замечу, что $_SESSION - это массив, мы используем всего лишь один элемент этого массива с индексом ‘session_message’.

В данном случае имеем дело с "массивом массивов" - то, что мы храним в элементе ‘session_message’, представляет собой массив, это и есть список передаваемых сообщений (их, конечно, может быть несколько).

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

У вас может возникнуть вопрос. А зачем здесь нужны классы? Вполне можно было бы обойтись двумя функциями. Но давайте заглянем дальше. Нам может понадобиться создавать сообщения с различными типами (info, error, warning), определять адресатов сообщений.

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

Представим, что мы бы это делали с помощью функций. Наверное, у нас была бы функция message_send($txt), еще была бы функция message_to_page($txt). Теперь надо добавить возможность различного поведения для различных видов сообщений. Вызовы функций меняются: message_send($txt, $kind), message_to_page($txt, $kind). Придется прочесать весь код приложения в поисках таких функций, делая исправления.

Этого можно избежать, заранее предвидя ситуацию, представив сообщение в виде ассоциативного массива: $msg[‘txt’], $msg[‘kind’], тогда в вызовах функций будет только один параметр. Чувствуете, как это стремится превратиться в класс?

Так вот, ООП дает возможность позволить себе роскошь не продумывать все заранее.

Следующий класс - Inbox - как раз для этого и предназначен.

class Inbox { /** * Массив поступивших сообщений. */ var $messages = array(); /** * В конструкторе получаем все поступившие сообщения * и удаляем их из сессии. */ function Inbox() { if (is_array($_SESSION["session_messages"])) { $messages = $_SESSION["session_messages"]; $co = sizeof($messages); for ($i = 0; $i < $co; $i++) { $this->messages = new Message($messages[$i]); } } /* очищаем массив сообщений */ $_SESSION["session_messages"] = array(); } /** * Выводим на страницу содержимое Inbox. */ function toPage() { $co = sizeof($this->messages); if ($co > 0) { echo "Сообщение от системы:
"; } for ($i = 0; $i < $co; $i++) { $this->messages[$i]->ToPage(); } } }

Давайте испытаем нашу систему сообщений.

Создадим очень простой пример, который в ответ на отправку формы будет сообщать количество секунд в текущей минуте.

send(); /* перенаправление на себя же */ header("location:"); } else { $inbox = new Inbox(); $inbox->toPage(); } ?>

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

Создайте каталог на веб-сервере, затем создайте в нем эти три файла и попробуйте скрипт в работе. Заметьте, проблем с кнопками Back и Refresh не возникает.

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

Здесь мы встречаем два затруднения:

* Хотелось бы, чтобы список сообщений появлялся в определенной части страницы, и вы уже подобрали хорошее местечко для этого.
Проблема в том, что надо запустить команду $inbox->toPage() именно в тот момент, который бы соответствовал положению списка сообщений на странице. Если мы захотим поменять положение этого списка, придется лезть в код, но нехорошо постоянно для этого изменять каркас портала. Наилучшим решением было бы сделать вывод сообщений в виде отдельного модуля, о котором известно лишь только, что его надо подключить к каркасу.
То есть освободиться от строгой последовательности запуска модулей. Действительно, раз результат работы вывода Inbox не зависит от работы системы (на данном шаге - все данные у нас уже есть в сессии), то зачем лишние сложности?
* Чтобы поддерживать внешний вид (дизайн) списка сообщений надо заботиться об HTML-коде, который у нас зашит в методах toPage() классов Message и Inbox. Как правило, придется изменять PHP-код для того, чтобы изменить дизайн.

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

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

Уже эта попытка решения дает нам идею использовать XML как средство хранения промежуточных данных. А использование стилей XSLT поможет справиться и со втором проблемой.

Я не буду останавливаться на том, что такое XML, и что такое XSLT. Если вы не знакомы с этими вещами, zvon.org станет хорошей отправной точкой для изучения.

Идея в том, чтобы в методах toPage() формировать не HTML-код, а XML структуру. Документ страницы будет создаваться в виде стринга с XML-кодом (он будет служить в качестве "буфера"), а на последней стадии работы скрипта мы будем использовать XSL-трансформацию.

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

minute 57 second: 45

Что это такое - догадаться довольно просто - два сообщения и форма. Заметьте, PHP-скрипт должен подготовить только такой стринг - он очень простой. Причем порядок следования основных тегов неважен - можно поставить вначале, например, как будет удобно программисту. Как это реализовать. Можно, почти ничего не меняя, использовать output buffering, вместо HTML-кода выводить XML, а в конце просто захватить вывод в стринг. Но тогда мы потеряем в гибкости - например, хочется иногда выводить отладочную информацию прямо на страницу (с помощью echo). В то же время, разработчики PHP работают над DOM-модулем, который предлагает более продвинутый способ создания и передачи древовидных документов. Если мы захотим внедрить DOM, то придется перекраивать все приложение, изменяя вывод стрингов на создание DOM-элементов. Поэтому я предпочитаю хранить XML-представление объектов внутри самих объектов, последовательно собирая общий XML-документ. Это не так сложно, нужна всего лишь небольшая модификация. Вы увидите, что такой прием не привязан жестко к конкретному способу хранения XML-данных, и это позволит совершить переход к использованию DOM "малой кровью". Прежде всего заметим, что у каждого нашего объекта есть метод toPage(). Эта похожесть должна нас заставить задуматься о том, чтобы ввести новый общий родительский класс. Пусть каждый класс, который способен создавать кусочки XML-документа для страницы, будет наследоваться от класса, который будет заботиться об XML-представлении объекта. Назовем его Outputable.

class Outputable { /** * XML контейнер (стринг). */ var $output = ""; /** * Отдать содержимое контейнера и очистить контейнер. * * @return стринг с XML-данными */ function getOutput() { $out = $this->output; $this->output = ""; return $out; } /** * Добавить порцию к содержимому контейнера. * * @param string добавляемый стринг */ function appendOutput($string) { $this->output .= $string . "n"; } /** * "Абстрактный" метод. */ function toPage() { } }

Метод toPage() сделан пустым - в данном случае он нужен как индикатор того, как должны внешние "матрешки"-классы общаться с внутренним классом. Впрочем, здесь можно было бы предложить реализацию по умолчанию, если бы мы заметили, что есть много объектов, которые одинаково выводят себя на страницу.

Классы Message и Inbox несколько изменятся - теперь оба они должны наследоваться от Outputable, а также изменятся и методы toPage()
Message.php

class Message extends Outputable { /** * Содержание сообщения. */ var $content; /** * Конструктор для инициализации текста сообщения. * * @param content содержание сообщения */ function Message($content) { $this->content = $content; } /** * Запись сообщения в сессию. */ function send() { $_SESSION["session_messages"] = $this->content; } /** * Вывод сообщения на страницу. */ function toPage() { $this->appendOutput("".$this->content.""); } }

class Inbox extends Outputable { /** * Массив поступивших сообщений. */ var $messages = array(); /** * В конструкторе получаем все поступившие сообщения * и удаляем их из сессии. */ function Inbox() { if (is_array($_SESSION["session_messages"])) { $messages = $_SESSION["session_messages"]; $co = sizeof($messages); for ($i = 0; $i < $co; $i++) { $this->messages = new Message($messages[$i]); } } /* очищаем массив сообщений */ $_SESSION["session_messages"] = array(); } /** * Выводим на страницу содержимое Inbox. */ function toPage() { $co = sizeof($this->messages); $this->appendOutput(""); for ($i = 0; $i < $co; $i++) { $this->messages[$i]->toPage(); $this->appendOutput($this->messages[$i]->getOutput()); } $this->appendOutput(""); } }

Изменился способ вывода - теперь вместо непосредственного вывода на страницу внешнее представление до поры до времени хранится в Outputable, который "сидит" в каждом из объектов. Метод appendOutput() служит некоторой заменой конструкции echo(). Чтобы забрать вывод объекта, используется метод getOutput().

Теперь посмотрим, что собой представляет клиентская часть кода, которая будет решать ту же задачу, что и раньше.
index.php

send(); /* текущая секунда */ $msg_sec = new Message("second: " . date("s")); $msg_sec->send(); /* перенаправление на себя же */ header("location:"); exit; } else { /* подготавливаем список сообщений в виде XML */ $inbox = new Inbox(); $inbox->toPage(); $global_content->appendOutput($inbox->getOutput()); } $global_content->appendOutput(""); $xml_string = $global_content->getOutput(); $xh = xslt_create(); $xarg = array(); /* заголовок XML-документа */ $xarg["xml"] = ""."n"; /* тело XML-документа */ $xarg["xml"] .= "" . $xml_string . ""; /* XSL-шаблон */ $xarg["xsl"] = implode("", file("style.xsl")); /* выводим HTML-код - результат XSL-трансформации */ echo xslt_process($xh, "arg:xml", "arg:xsl", NULL, $xarg); /* выводим XML-исходник (debug) */ echo "


" . htmlspecialchars($xml_string) . "
"; ?>

Главное новшество - в объекте $global_content, название которого говорит само за себя. В данном случае он принадлежит классу Outputable, в реальных задачах вы, наверное, создадите отдельный класс для контента страницы.

Если внимательно присмотреться, то содержательная часть скрипта практически не изменилась - тот же inbox, тот же toPage(). Добавлена инструкция, которая содержимое списка сообщений выводит в контент страницы. Для разнообразия теперь генерируется два сообщения.

Для того, чтобы посмотреть на результат, осталось только подготовить XSL-шаблон.
style.xsl

XSLT Example

message

Чего же мы добились?

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

Любой модуль, который генерирует XML-данные в качестве результата своей работы, может быть использован в проекте. Кстати, это одно из преимуществ перед template-движками, в которых создание данных заключается в последовательности вызова методов (assign и т.п.) конкретного движка, на которых нет общего стандарта.

Еще одно преимущество - легкость отладки. Если вы запустите скрипт, то заметите, что на каждой странице присутствует debug-вывод - XML-прообраз, который здорово упрощает отладку приложений.

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

Напоследок, галопом о перспективах:

* всплывающие окна для списка важных сообщений
* "страницы-отправители" и "страницы-адресаты" в сообщениях
* ведение лога сообщений в базе данных
* кнопка "показать историю моих действий"
* статистический анализ действий пользователей в пределах сессий
* "интеллектуальные помощники" в веб-приложениях

Общие понятия

Язык PHP специально предназначен для веб-программирования. PHP сочетает достоинства языков C и Perl и при этом весьма прост в изучении и обладает значительными преимуществами перед традиционными языками программирования.

Синтаксис PHP очень напоминает синтаксис языка C и во многом заимствован из таких языков как Java и Perl.

Программист С очень быстро освоит язык PHP и сможет использовать его с максимальной эффективностью.
В принципе, в PHP есть практически все операторы и функции , имеющиеся в стандартном GNU С (или их аналоги), например есть циклы (while, for), операторы выбора (if, switch), функции работы с файловой системой и процессами (fopen, *dir, stat, unlink, popen, exec), функции ввода-вывода (fgets,fputs,printf) и множество других...

Цель данного раздела - краткое ознакомление с основами синтаксиса языка PHP. Более подробную информацию по конкретным составляющим синтаксиса PHP вы найдете в соответствующих разделах.

PHP и HTML

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



Пример

echo "Привет, я - скрипт PHP!" ;
?>


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

Обратите внимание, что HTML-код корректно обрабатывается интерпретатором PHP.

Начало сценария вас может озадачить: разве это сценарий? Откуда HTML-тэги и ? Вот тут-то и кроется главная особенность (кстати, чрезвычайно удобная) языка PHP: PHP-скрипт может вообще не отличаться от обычного HTML-документа.

Идем дальше. Вы, наверное, догадались, что сам код сценария начинается после открывающего тэга и заканчивается закрывающим ?> . Итак, между этими двумя тэгами текст интерпретируется как программа, и в HTML-документ не попадает. Если же программе нужно что-то вывести, она должна воспользоваться оператором echo.

Итак, PHP устроен так, что любой текст, который расположен вне программных блоков, ограниченных и ?> , выводится в браузер непосредственно. В этом и заключается главная особенность PHP, в отличие от Perl и C, где вывод осуществляется с помощью стандартных операторов.

Разделение инструкций

Инструкции разделяются также как и в C или Perl - каждое выражение заканчивается точкой с запятой.

Закрывающий тег (?>) также подразумевает конец инструкции, поэтому два следующих фрагмента кода эквиваленты:

echo "Это тест" ;
?>

Комментарии в PHP скриптах

Написание практически любого скрипта не обходится без комментариев.

PHP поддерживает комметарии в стиле "C", "C++" и оболочки Unix. Например:

echo "Это тест" ; // Это однострочный комментарий в стиле c++
/* Это многострочный комментарий
еще одна строка комментария */
echo "Это еще один тест" ;
echo "Последний тест" ; # Это комментарий в стиле оболочки Unix
?>

Однострочные комментарии идут только до конца строки или текущего блока PHP-кода, в зависимости от того, что идет перед ними.

Это пример.


Заголовок вверху выведет "Это пример".

Будьте внимательны, следите за отсутствием вложенных "C"-комментариев, они могут появиться во время комментирования больших блоков:

/*
echo "Это тест"; /* Этот комментарий вызовет проблему */
*/
?>

Однострочные комментарии идут только до конца строки или текущего блока PHP-кода, в зависимости от того, что идет перед ними. Это означает, что HTML-код после // ?> БУДЕТ напечатан: ?> выводит из режима PHP и возвращает в режим HTML, но // не позволяет этого сделать.

Переменные в PHP

Имена переменных обозначаются знаком $ . То же самое "Привет, я - скрипт PHP! " можно получить следующим образом:

$ message = "Привет, я - скрипт PHP!" ;
echo $ message ;
?>

Типы данных в PHP

PHP поддерживает восемь простых типов данных:

Четыре скалярных типа:

Boolean (двоичные данные)
- integer (целые числа)
- float (числа с плавающей точкой или "double")
- string (строки)

Два смешанных типа:

Array (массивы)
- object (объекты)

И два специальных типа:

resource (ресурсы)
NULL ("пустые")

Существуют также несколько псевдотипов:

Mixed (смешанные)
- number (числа)
- callback (обратного вызова)

Подробно о типах данных в PHP

Выражения в PHP

Основными формами выражений являются константы и переменные. Например, если вы записываете "$a = 100", вы присваиваете "100" переменной $a:

В приведенном примере $a - это переменная, = - это оператор присваивания, а 100 - это и есть выражения. Его значение 100.

Выражением может быть и переменная, если ей сопоставлено определенное значение:

$x = 7;
$y = $x;

В первой строке рассмотренного примера выражением является константа 7, а во второй строке - переменная $x, т.к. ранее ей было присвоено значение 7. $y = $x также является выражением.

Подробно о выражениях в PHP вы найдете

Операторы PHP

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

Примеры операторов PHP:

Операторы присвоения:

$a = ($b = 4 ) + 5 ; // результат: $a установлена значением 9, переменной $b присвоено 4.

?>

Комбинированные операторы:

$a = 3 ;
$a += 5 ; // устанавливает $a значением 8, аналогично записи: $a = $a + 5;
$b = "Hello " ;
$b .= "There!" ; // устанавливает $b строкой "Hello There!", как и $b = $b . "There!";

?>

Строковые операторы:

$a = "Hello " ;
$b = $a . "World!" ; // $b содержит строку "Hello World!"

$a = "Hello " ;
$a .= "World!" ; // $a содержит строку "Hello World!"
?>

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

Подробную информацию по операторам PHP вы найдете .

Управляющие конструкции языка PHP

Основными конструкциями языка PHP являются:

  1. Условные операторы (if, else);
  2. Циклы (while, do-while, for, foreach, break, continue);
  3. Конструкции выбора (switch);
  4. Конструкции объявления (declare);
  5. Конструкции возврата значений (return);
  6. Конструкции включений (require, include).

Примеры конструкций языка PHP:

if ($a > $b ) echo "значение a больше, чем b" ;
?>

Приведенный пример наглядно показывает использование конструкции if совместно с оператором сравнения ($a > $b).

В следующем примере если переменная $a не равна нулю, будет выведена строка "значение a истинно (true), то есть показано взаимодействие условного оператора (конструкции) if с логическим оператором:

if ($a ) echo "значение a истинно (true) " ;
?>

А вот пример цикла while:

$ x = 0 ;
while ($ x ++< 10 ) echo $ x ;
// Выводит 12345678910
?>

Информацию по всем управляющим конструкциям PHP вы можете получить

Пользовательские функции в PHP

В любом языке программирования существуют подпрограммы. В языке C они называются функциями, в ассемблере - подпрограммами, а в Pascal существуют два вида подпрограмм: процедуры и функции.

В PHP такими подпрограммами являются.

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

Приведем пример пользовательской функции на PHP:

function funct () {
$a = 100 ;
echo "

$a

" ;
}
funct ();

?>

Сценарий выводит 100:

Пользовательским функциям в PHP можно передавать аргументы и получать возвращаемые функциями значения.

Подробную информацию по пользовательским функциям PHP вы найдете

Встроенные (стандартные) функции PHP

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

ООП и PHP

PHP имеет достаточно хорошую поддержку объектно-ориентированного программирования (ООП).

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

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

// Создаем новый класс Coor:
class Coor {
// данные (свойства):
var $ name ;

// методы:
function Getname () {
echo "

John

" ;
}

}

// Создаем объект класса Coor:
$ object = new Coor ;
// Получаем доступ к членам класса:
$ object -> name = "Alex" ;
echo $ object -> name ;
// Выводит "Alex"

Есть еще вопросы или что-то непонятно - добро пожаловать на наш

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

Такой подход, насколько я понимаю, широко применяется в мире Java, там для этого есть стандарт Java Message Service (JMS) и применяются брокеры сообщений и на этом базируется архитектура Enterprise service bus (ESB), например, Apache ServiceMix . Но для нас это пока высокая сфера крупных проектов, а в специфике веба и веб-ориентированных приложений я бы хотел рассмотреть, можно ли что-то сделать подобное, но с меньшими затратами и обеспечить приложению отказоустойчивость, распределение нагрузки и асинхронную обработку. И конечно, очень желательно, чтобы это было реализовано на РНР как основном языке реализации всех компонентов сервера.

И так, еще раз - MQ, это архитектура и ПО промежуточного уровня, которое занимается сбором, хранение и маршрутизацией (распределением) сообщений между компонентами. Я не претендую на полноту описания, и, вполне возможно, не учитываю множества нюансов, поэтому не рассматривайте мои определения как аксиомы, лучше всего почитать дополнительную литературу, если вы хотите поглубже разобраться в архитектуре MQ (например, вот эти статьи: , , ) и определение в Wikipedia - Message queue

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

Apache ActiveMQ - открытая реализация брокера сообщений (Message Broker) и Enterprise Integration Patterns (если сейчас и очень кратко - расширение для реализации дополнительной обработки согласно правилам). Этот проект, по моему мнению, из всех открытых, самый мощный и развивающийся, недавно вышла версия 5.1. Он реализовывает множество стандартов и обеспечивает все возможности, необходимые для решений уровня Enterprise, входит в стек Java-технологий от Apache. Что меня заинтересовало, так это возможность кросс-языкового обмена сообщениями, а значит - клиенты могут быть реализованы на любом языке. Для платформ Java, C, C++, C# это библиотека OpenWire , реализующая Wire протокол для нативного доступа к MQ, для остальных языков, включая, что нам и интересно, РНР, есть Stomp - реализация библиотек для разных скриптовых языков, которая превращает сообщения в формат JMS. Кстати, если необходимо обеспечить безопасную коммуникацию и передачу сообщений, можно использовать SSL.

MQS (Minimalist Queue Services) - проект, если можно так сказать, с друго конца. Это небольшая система, написанная на Perl, организовывает систему очередей сообщений, используя XML-RPC протокол, сами сообщения могут хранится как в любой базе данных, так и в файлах. К сожалению, по всей видимости, проект заброшен, так как последняя новость на сайте датирована апрелем 2005 года, а текущая версия - 0.0.14.

Spread - еще одна реализация очереди сообщений, на этот раз на С++, и версии есть для различных платформ, включая Win32, Linux, BSD и MacOS. Текущая версия - 4.0. Система распределенная и ориентирована на высокопроизводительные системы, где клиентов и, соответственно, сообщений, очень много. Заявлена поддержка, в последней 4.0 версии, технологии Virtual Synchrony . Что интересно - в поставку сразу включены бинарные версии для нескольких платформ, а также встроенные интерфейсы для некоторых языков - C/C++, Java, Perl, Python, Ruby. Странно, что четвёртого Р - РНР, среди них нет, но существует расширение в PECL , которое реализовывает весь интерфейс Spread API. Текущая версия 2.1 и достаточно новая, значит проект развивается. Существуют и реализации для других языков, в том числе и альтернативы встроенным интерфейсам, поэтому посмотрите на , там даже для MS Excel есть расширение. Среди интересных проектов - модуль mod_log_spread для Apache , позволяющий собирать логи доступа с нескольких веб-серверов.

RabbitMQ - высокопроизводительная платформа, написанная на Erlang, основанная на Open Telecom Platform, а значит - очень надежная и масштабированная система, часто применяемая в телекоммуникационных приложениях и других подобных системах. Есть интерфейс только для Java и C++. Система поддерживает стандарт AMQP (Open Standard for Messaging Middleware). Система интересная, знать бы только Erlang, хотя что-то мне подсказывает, что проектируя весь серверный модуль на этой платформе, мы получили бы много "плюшек", в частности, на этой же платформе написан самый популярный Jabber-сервер ejabberd, который также можно применять в он-лайн игровых проектах.

Beanstalkd - также интересный проект, созданный в рамках разработки одного из приложений для социальной сети Facebook, которым пользуется около 10 млн человек (приложением, не сетью). Это специализированный сервер для хранения и обработки очередей заданий, использующий хранение данных в памяти для обеспечения скорости, однако в ущерб отказоустойчивости. Этот проект очень похож на уже ранее , да и сами разработчики выражают благодарность создателям memcached за принципы архитектуры и протокол. Система предназначена для создания асинхронной очереди обработчиков пользовательских задач, которые не требуют немедленного ответа, например, отсылки писем, фоновые обработки и т.п. Существуют клиентские API для различных языков, в том числе для Erlang, OCaml, Perl, PHP, Python, Ruby. Для РНР библиотека и пока имеет версию 0.11, сама разработка началась всего пару месяцев назад (судя по регистрации проекта). Детальнее можно почитать отличный обзор: Beanstalk Messaging Queue Сервер написан на С, что обеспечивает высокую скорость работы, однако специфика проекта в плане хранения всех данных в оперативной памяти не подойдет для тех сфер, где остро необходима максимальная отказоустойчивость, пусть даже ценой дополнительного ПО и затрат на хранение данных в базе.

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

Последнее обновление: 1.11.2015

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

Программа или скрипт на PHP, как правило, находится в файле расширением .php . Хотя разработчики могут также вставлять код php и в файлы с расширениями .html/.htm .

Когда пользователь обращается к скрипту в адресной строке браузера, набирая, например, http://localhost:8080/display.php , то веб-сервер передает его интерпретатору PHP. Затем интерпретатор обрабатывает код и генерирует на его основе html-разметку. И затем сгенерированный html-код отправляется пользователю.

Документ PHP может содержать как разметку html, так и код на языке php. Для перехода от разметки html к коду php используются теги , между которыми идет код php. Данные теги служат указанием интерпретатору, что их содержимое надо интерпретировать как код php, а не разметку html.

Также можно использовать краткую версию тегов: . Для этого в файле php.ini надо изменить значение short_open_tag = Off на short_open_tag = On

Рассмотрим простейший скрипт на php:

Веб-сайт Привет мир!

"; echo "2 + 2 = " . (2+2); ?>

После обработки файла интерпретатор сформирует следующую разметку:

Веб-сайт

Привет мир!

2 + 2 = 4

Здесь использованы две инструкции echo "

Привет мир!

" и echo "2 + 2 = " . (2+2) , который выводят определенное значение на страницу. Каждая отдельная инструкция в PHP завершается точкой с запятой.

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

Используется он для создания веб-проектов. Может использоваться прямо в HTML коде. И хотя результат работы скрипта часто выводится непосредственно в браузере клиента, для работы PHP не достаточно только одного браузера. То-есть вам не получится запустить index.php файл прямо в браузере, как вы уже наверняка делали с файлом index.html. Для работы PHP сценариев и веб-страниц созданных с применением PHP потребуется веб-сервер.

Если у вас еще нет хостинг площадки для вашего сайта, тогда рекомендую поэкспериментировать с PHP сценариями на локальном сервере, предназначенном для тестирования проектов. Для организации локального сервера в операционной системе Windows (WAMP, Windows-Apache-MySQL-PHP) могут быть полезны пакеты: Денвер, XAMPP, AppServ, OpenServer и т.д. После установки этих пакетов, вы получите уже настроенный и готовый к использованию сервер, а управляться он будет через удобное меню самой программы. Также, существуют и отдельные реализации APACHE, MySQL и PHP для операционной системы Windows, но настраивать их придется уже самостоятельно через конфигурационные файлы и не будет никакого меню с галочками. Для запуска, перезапуска и остановки такого сервера можно будет использовать пакетные файлы *.bat или *.cmd (батник) с командами запуска, перезапуска или остановки служб APACHE и MySQL. Третий и самый непростой для новичка вариант — это виртуальная машина с установленной и настроенной операционной системой Linux (LAMP, Linux-Apache-MySQL-PHP). Готовые образы таких «виртуалок» часто встречаются в Интернете, так что вам могут понадобиться только знания настройки программ типа VirtualBox или VMware.

Подготовка к программированию на языке PHP для чайников

  1. PHP код следует помещать в файле index.php, сам файл должен быть размещен в корневом каталоге сайта, расположенного на веб-сервере.

  1. Весь код на языке PHP должен быть заключен между дескрипторами или сокращенный вариант , но веб-сервер может быть не сконфигурирован для использования сокращенного варианта такой записи, поэтому предпочтителен первый вариант.
  2. Вставлен PHP код может быть в любое место HTML кода.
  3. Комментирование в PHP коде осуществляется следующим образом:
// однострочный комментарий # еще один вариант однострочного комментария /* многострочный комментарий */
  1. Для того, чтобы посмотреть ваш код, откройте веб-браузер и в адресной строке введите: http://localhost/www/MyEX/index.php

Вывод данных на экран с помощью языка PHP для чайников

  1. Вывод данных в окно (клиентскую область веб-браузера) с помощью PHP можно выполнить посредством оператора echo. Этот оператор позволяет вывести данные различных типов: числа, символьные строки и т.д.
  2. Синтаксис оператора вывода:
echo элемент1, элемент2, элемент3, ..., элементN
  1. Строковые данные заключаются в двойные или одинарные кавычки. В двойных кавычках код интерпретируется PHP. Все, что заключено в одинарные кавычки выводится без какой бы ни было интерпретации. Пример:
< ?php $x="PHP"; //присвоение значения переменной echo "Привет","всем"; echo " "; echo "

Пример $x кода

Пример $x кода

  1. Для вывода более подробной информации о переменной, которая может понадобиться при отладке программы, служит функция var_dump(). Ее синтаксис:
var_dump(cписок переменных);
  1. В списке переменных указывается одно или несколько имен переменных. Эта функция ничего не возвращает. Пример:
$x=12.56; var_dump($x);
  1. Менее информативной, чем var_dump(), функцией вывода сведений о переменных является:
print_r(список_переменных);
  1. Для переменных типа «массив» эта функция выводит список вида индекс => элемент.

Переменные языка РНР для чайников

  1. Переменные – контейнеры для хранения данных. Данные, сохраняемые в переменной, называют значением этой переменной.
  2. Переменная имеет имя – последовательность букв, цифр и символа подчеркивания без пробелов и знаков препинания, начинающаяся обязательно с символа доллара ($), за которым должна следовать буква или символ подчеркивания.
  3. Правильные имена переменных: $_tel, $tmp, $my_, $address_234_45.
  4. Неправильные имена переменных: $234tel, my address, $tel:234.
  5. РНР является регистро-ависимым языком относительно имен переменных и констант. Однако ключевые слова могут использоваться в любом регистре.

Типы данных языка РНР и преобразование данных для чайников

Тип данных Пример Описание значений
Строковый или символьный (string) «Привет всем»
«123456»
«25 рублей»
Последовательность символов, заключенная в кавычки
Целочисленный, числовой (integer) -234
25
0
Число или последовательность цифр, перед которыми может быть указан знак числа
Числовой с плавающей точкой (float) 5.47
21.4
35E-3
Число с дробной частью (35Е2 означает 3500)
Логический (булевый, boolean) true
false
Этот тип имеет два значения: true (истина, да), false (ложь, нет)
NULL null Этот тип данных имеет одно значение — null
Массив (Array) Этот тип данных имеет одно множество значений, которые могут быть различных типов
Объект (Object) Программный объект, определяемый своими свойствами
  1. Для того, чтобы узнать какой тип переменной, нужно воспользоваться функцией:
gettype(имя_переменной);
  1. Для явного задания типа можно воспользоваться одним из двух способов:
Имя_переменной=(int) 12.45 //результат 12 Settype(имя_переменной, "тип") < ?php $x="PHP"; $s=gettype($x); echo $s, " "; settype($e,"integer"); $s=gettype($e); echo $s, " "; $d=(int)24.4; $s=gettype($d); echo $s, " ", $d; ?>

Константы языка PHP для чайников

  1. Константой называется именованная величина, которая не изменяется в процессе выполнения программы (скрипта).
  2. В отличие от переменных, вы не можете изменять значения констант, которые были им присвоены при их объявлении. Константы удобно использовать для хранения значений, которые не должны изменяться во время работы программы. Константы могут содержать только скалярные данные (логического, целого, плавающего и строкового типов).
  3. В РНР константы определяются функцией define(). Вот ее синтаксис:
define($name, $value, $case_sen);

$name — имя константы.
$value — значение константы.
$case_sen — необязательный параметр логического типа, указывающий, следует ли учитывать регистр букв (true) или нет (false).

Define("pi",3.14,true); echo pi; //Выводит 3.14

  1. Для проверки существования константы можно использовать функцию defined(). Данная функция возвращает true, если константа объявлена. Пример:
//Объявляем константу pi define("pi",3.14,true); if (defined("pi")==true) echo "Константа pi объявлена!"; //Скрипт выведет "Константа pi объявлена!"

Различия между константами и переменными в языке PHP для чайников

  1. У констант нет приставки в виде знака доллара ($).
  2. Константы можно определить только с помощью функции define(), а не присваиванием значения.
  3. Константы могут быть определены и доступны в любом месте без учета области видимости.
  4. Константы не могут быть определены или аннулированы после первоначального объявления.
  5. Константы могут иметь только скалярные значения.

Программирование на языке PHP для чайников. Часть 1 was last modified: Март 3rd, 2016 by Admin