Создание UI на PHP для IBM Lotus Domino (исходники)Источник: IBM developerWorks Россия Андрей Кувшинников, главный разработчик Domino-приложений, Botstation
В данной статье вы узнаете, как взаимодействовать с базами данных IBM Lotus Domino из Web-приложений, созданных на языке программирования PHP. Вы также узнаете, как обращаться к Domino-приложениям из PHP-страниц, используя COM-объект, интерфейс прикладного программирования IBM Lotus Notes (application programming interface - API) и XML. В разделе "Загрузка" приведены ссылки на примеры кода для каждого метода. Для XML-метода можно также загрузить пример приложения с простым Web-интерфейсом к почтовой базе IBM Lotus Domino (см. рисунок 1). Рисунок 1. Пример пользовательского интерфейса на PHP к почтовой базе данных
PHP - это мощный встроенный язык программирования. Он свободно доступен для использования и популярен при разработке динамических Web-приложений. PHP-код не компилируется; он интерпретируется во время выполнения. Большая часть синтаксиса позаимствована из языков программирования C, Java и Perl. Можно добавить PHP как CGI-механизм (Common Gateway Interface) на большинстве Web-серверов. Он работает на операционных системах Microsoft Windows и Linux. Кроме того, более 50% компаний, предоставляющих Web-хостинг, имеют сервера, работающие с PHP. Из-за такого широкого распространения технологии вы просто не можете оставаться не знакомыми с ней. Работа с PHPPHP-код включается в Web-страницы при помощи специальных тегов. PHP-код начинается с тега <php и заканчивается тегом ?>:
Web-сервер интерпретирует этот простой пример и преобразовывает его в следующий HTML-код:
Web-страницы с PHP могут взаимодействовать с базами данных Domino несколькими способами. Выбор метода интеграции зависит от используемой для запуска PHP операционной системы, имеющихся ограничений системы защиты между серверами PHP и Domino, и того, что вам разрешено устанавливать на PHP-сервере. В данной статье рассматриваются следующие методы:
Автономное выполнение PHP-кода Хотя PHP изначально предназначался для работы на Web-сервере, а не для автономных приложений, его можно запустить из командной строки как программу сценариев командного процессора, аналогичную Microsoft Visual Basic Scripting Edition (VBScript). Эта возможность может быть полезна для автономного тестирования перед размещением файлов на Web-сервере. Доступ к Lotus DominoДля доступа к базе данных Domino доступны три метода: через COM-объекты, через Notes API и через XML. Доступ к Lotus Domino с использованием Domino COM-объектовСамым простым и наиболее быстро реализуемым методом доступа к информации, хранящейся в базах данных Domino, являются Domino COM-объекты. Использование COM из PHP не намного сложнее, чем из LotusScript. В следующем примере кода показано, как распечатать значения полей всех документов в виде.
На рисунке 2 показана информация, выводимая при выполнении этого COM-объекта в командной строке. Рисунок 2. Результат выполнения кода COM-объекта в командной строке
Использовать COM-объекты легко, но существуют некоторые препятствия, ограничивающие применение COM. Главным препятствием является необходимость установки клиента Lotus Notes на PHP-сервере. Если вы работаете с Web-хостинговой компанией для размещения PHP-приложений, не просто убедить ее установить Notes-клиент только для вашего PHP Web-сайта. Если вы имеете собственный PHP-сервер или, возможно, серверы PHP и Domino на одном и том же компьютере, у вас не должно возникнуть проблем в настройке COM-доступа к серверу Domino. Второй проблемой, ограничивающей применение COM, является поддержка COM-объектов только на платформе Windows. Принимая во внимание, что большинство PHP-серверов работают на Linux-платформе, это требование значительно уменьшает количество доступных серверов, способных разместить ваше COM-решение, даже если вы имеете полный административный контроль над этими серверами. Доступ к Lotus Domino через APIАльтернативой COM-доступу является использование Lotus Notes/Domino C API. Теоретически, вы можете использовать это решение на операционных системах, отличных от Windows. Мы рекомендуем это только программистам, имеющим хороший опыт работы с языками программирования C/C++ (если имеется причина не использовать COM-интерфейс или XML). Предоставляемая в примере API-решения функциональность ограничена, и вы должны написать свой собственный код на языке C для выполнения большинства задач. Пример библиотеки предоставляет хороший пример для создания PHP-расширений. Он поставляется только в исходном коде, и для компилирования его у вас должен иметься компилятор Visual C и набор инструментальных программ Domino C API. Для удобства мы скомпилировали исходный код в DLL-файл и включили ссылку на него в раздел "Загрузка". Активировать Notes-расширение можно, добавив следующую строку в конфигурационный файл php.ini:
Следующий пример кода показывает, как использовать эту методику после создания требуемых DLL.
На рисунке 3 показаны результаты выполнения API-кода в командной строке. Рисунок 3. Результат выполнения API-кода
Доступ к Lotus Domino с использованием XMLИспользование XML для взаимодействия с базами данных Domino является самым совместимым решением. При этом не требуется каких-либо дополнительных настроек или установок на PHP Web-сервере, и этот способ работает на всех операционных системах. По нашему мнению, это наилучшее решение для большинства случаев. В XML-решении, рассматриваемом в данной статье, используются технические приемы, которые наверняка будут работать в большинстве конфигураций. В качестве примера создадим PHP-интерфейс к стандартной почтовой базе данных Domino. Единственным изменением в среде Domino является LotusScript-агент для просмотра полей из почтовых документов. Этот же агент используется для синтаксического анализа XML, для создания и передачи почтовых сообщений. Для просмотра папки Inbox почтовой базы данных выполните следующие действия:
Для доступа к базам данных Domino необходима функциональность как для получения Web-страниц с сервера Domino, так и для синтаксического анализа XML. Для демонстрационного приложения также необходимо обеспечить следующие условия:
Примечание: Если вы не можете обратиться к серверу Domino из сети Интернет, возможно, надо настроить конфигурацию вашего брандмауэра, чтобы разрешить трафик от PHP-сервера. PHP-функции для чтения Web-файлов DominoPHP имеет несколько функций для извлечения Web-содержимого. Эти функции были включены в PHP с самого начала, но администраторы не всегда активировали их. Извлекать файлы из Web могут следующие функции:
Примечание: В примере приложения в данной статье вы встретите исключительно функцию file_get_contents(). Получение сессионных куки Domino является важной частью процесса, и можно использовать аналогичный код в других Domino-приложениях. Например, можно извлечь куки для входа на сервер IBM Lotus Sametime, используя STLinks. Получить куки можно путем передачи POST-запроса серверу Domino. В этот запрос включите ваше имя пользователя и пароль. Ответ от сервера будет содержать куки, которые используются в последующих запросах к серверу Domino. При включении в запрос сессионных куки сервер Domino считает, что ваш сценарий является реальным пользователем, который недавно зарегистрировался в системе и теперь обращается к базе данных. Метод POST используется вместо GET потому, что URL-адреса метода GET записываются в log-файл Domino, и любой, кто имеет доступ к нему, может увидеть имя пользователя и пароль в виде обычного текста. При использовании метода POST имена пользователей и их пароли не являются частью URL; следовательно, они не видимы в обычных log-файлах. Сессионные куки Domino можно найти в заголовке ответа Set-Cookie. Сессионные куки называются либо DomAuthSessId, либо LtpaToken. Имя LtpaToken используется, если сервер Domino настроен на единую регистрацию (single sign-on - SSO). Вам не нужно заботиться о том, как называются куки; вы просто сохраняете всю строку. В следующем примере кода показано, как извлечь куки.
В строке кода $req="username=john+doe&password=john123" указывается корректное имя пользователя и пароль, которые будут использоваться для регистрации на сервере Domino. Затем настраиваются дополнительные параметры, такие как тип метода POST и другие заголовки. После этого к исходящему HTTP-запросу применяются ваши дополнительные параметры:
Из полученного от сервера Domino ответа извлекаются все заголовки при помощи функции stream_get_meta_data($fp), а также выполняется цикл по всем заголовкам, пока не найдется заголовок, содержащий строку Set-Cookie. После этого куки сохраняются путем записи в сессионную переменную:
$_SESSION хранит значения куки до закрытия Web-браузера. Теперь нужно использовать эти куки в следующем запросе, извлекающем вид/папку Inbox из почтовой базы данных Domino.
В этот раз для загрузки Web-страницы используется метод GET вместо метода POST. Этот метод указывается строкой 'method'=>"GET" в массиве HTTP-параметров. Вместо чтения только заголовков при помощи функции file_get_contents(URL, false, context) читается ответ полностью. Результатом этой операции является длинная XML-строка, содержащая все столбцы из вида Inbox. К заголовку добавляются сессионные куки:
После получения XML-данных можно обработать их в PHP XML-анализаторе. Затем создается ваш собственный пользовательский интерфейс для вида Inbox. PHP-функции для обработки XMLВ PHP, также как и в языках программирования LotusScript и Java, существует два способа обработки XML-кода: SAX (Simple API for XML) и DOM (Document Object Model). SAX - это ориентированная на события программная модель. Она включена и разрешена по умолчанию на большинстве PHP Web-серверов. Расширение DOM должно быть активировано администратором Web-сервера. Хотя с DOM намного легче работать, в наших примерах используется SAX-анализатор, поскольку мы хотим достичь максимальной совместимости с большинством PHP-конфигураций. Аналогичные обработке Domino-видов методики могут (с небольшими изменениями) быть использованы для работы с другими источниками XML-данных, такими как RSS-фиды и даже Web-службы. Следующий пример кода отображает XML в виде Inbox, содержащем один документ.
Как видите, документы в XML-источнике представлены тегом <viewentry>, а столбцы (поля) представлены тегами <entrydata>. Universal ID документа доступен как атрибут узла <viewentry>. Все, что нужно сделать, - определить способ программно найти значения между этими тегами для получения всех нужных данных. Звучит просто и также просто реализуется. Прежде всего, инициализируйте объект XML-анализатора, используя функцию xml_parser_create:
Затем настройте функции обратного вызова, которые отвечают за обработку начальных и конечных элементов XML. Эти функции указываются процессору при помощи функций xml_set_element_handler и xml_set_character_data_handler. Каждая функция принимает дескриптор анализатора и имена функций обратного вызова:
Необходимо добавить функции startElement, endElement и textData в ваш PHP-код:
Итак, давайте посмотрим, как это работает. Когда XML-анализатор проходит по XML-источнику и находит начало нового элемента, он активизирует функцию startElement, которая была указана как функция обратного вызова. В данном случае таким начальным элементом является <ENTRYDATA>. Теперь вы знаете, что текущим обрабатываемым элементом является новый столбец, поэтому можно установить переменную $current_column в номер строки. В данном случае столбцы представляют поля:
После этого анализатор находит текст внутри узла <ENTRYDATA> и передает его в функцию textData, которая была указана как функция обратного вызова. Цель данной функции - разрешить вам заполнить массив значениями, находящимися внутри узла <ENTRYDATA>:
В примере XML-источника строкой кода $doc_coll[$current_doc][$main][$current_column] = "$data" является:
Это означает, что восьмым столбцом в виде Inbox для документа с Universal ID 38B16601EC8B42BAC12571440068335C является "seen Mickey?", что, кстати, является темой почтового сообщения. XML-анализатор "умный" и знает, что если элемент имеет начало, где-то должен быть конец. Поэтому, когда он находит конец элемента, он сигнализирует вам, активизируя функцию endElement (все верно - это та же функция, которую вы указали в качестве второй функции обратного вызова). В ней номер столбца сбрасывается, поскольку он больше не нужен. Также проверяется, нужно ли увеличить счетчик документов. В качестве счетчика для массива, хранящего идентификаторы Universal ID, используется переменная $doc_counter. Вы должны сохранять Universal ID вручную, для того чтобы добавить ссылки в почтовые документы. Когда вы знаете, что элемент VIEWENTRY завершился, это означает, что на подходе новый Universal ID, и лучше увеличить текущий индекс массива на 1 для сохранения массивов $doc_coll и $unids неповрежденными:
Если вы загрузите пример приложения и запустите на вашем собственном сервере, ваша версия почтовой базы данных Domino может иметь другое расположение столбцов в видах почтовой системы. Если это так, нужно скорректировать номера столбцов в PHP-коде (docfunctions.php). Пример PHP-приложения и LotusScript-агентаВ данном разделе рассматривается Domino-агент ProcessDocWebAction (включенный как часть примера приложения), который вы можете загрузить. Агент программируется на LotusScript и использует DOM для анализа входящих XML-запросов. Поскольку он использует новые классы XML-сценариев, можно его запускать на серверах Domino версий 6 и 7, но не на серверах версии 5. Запросы, которые обрабатывает этот агент, формируются в примере PHP-приложения и могут быть следующих типов:
Для развертывания агента выполните следующие действия:
Одним из основных приоритетов при создании примера PHP-приложения была гарантия его работы на всех стандартных почтовых базах данных без изменения дизайна. Вот почему это приложение не требует каких-либо изменений в дизайне почтовой базы данных. Вы можете разместить агент для обработки XML не в пользовательской почтовой базе данных, и этот же агент может быть использован для обслуживания всех пользователей. Когда пользователь выполняет процесс аутентификации первый раз, PHP-приложение после получения сессионных куки запрашивает у этого агента месторасположение пользовательского почтового файла. Агент знает, кто его запустил, поскольку он выполняется с активизированным свойством "Run as Web user". После этого начального запроса путь к пользовательской базе данных сохраняется для повторного использования до закрытия Web-браузера или завершения времени жизни сессии. Пользователь всегда регистрируется в системе, используя реальную систему аутентификации Domino. Пользователь не может обратиться к какому-либо ресурсу, к которому он или она не может обратиться через Web-браузер, даже если этот пользователь мог бы изменить исходный PHP-код на Web-сервере. ЗаключениеЕсли вы являетесь разработчиком Domino-приложений или администратором сервера Domino, и ваш сервер недоступен из Интернета, вы все равно можете предоставить пользователям способ доступа к данным, хранящимся в базах данных Domino, и разрешить им читать и писать почтовые сообщения. Используя приемы работы с XML, описанные в данной статье и примененные в примере приложения, вы можете легко реализовать Domino-аутентификацию в ваших собственных PHP-приложениях для проверки регистрационной информации в Domino Directory. Здесь нет переопределения прав доступа пользователей; пользователь использует свои полномочия в каждой операции. Это гарантирует недоступность для пользователей неавторизованных данных. Для дальнейшего повышения защищенности вы можете реализовать регистрацию неудачных попыток входа в систему. |