Лучших работников в сфере IT РАБОТА-КА Вам поможет найти! о нас ✈
Я ищу работу в IT сфере ✈ Я ищу резюме в IT сфере ✈
Инженер схемотехник! 80000-100000 руб. ТК. соц.пак. Подробнее ✈

Использование XML и PHP для создания единого списка контактов, адаптируемого к различным телефонам


Людям, постоянно находящимся в разъездах, необходимо иметь согласованные и достоверные списки контактов во всех телефонах, которыми они пользуются. В этой статье рассмотрен пример, в котором данные для стационарного SIP-телефона и мобильного смартфона извлекаются из базы данных MySQL. Из статьи вы узнаете, как с помощью PHP получить настраиваемый XML-код из одной и той же базы данных, подходящий для использования как в стационарных, так и в мобильных телефонах.
Даже если вы находитесь в командировке или где-то еще, вам необходимо иметь связь со всеми людьми из вашего списка контактов. Когда вы находитесь в офисе, вы совершаете звонки с помощью стационарного VoIP-телефона, а в пути пользуетесь смартфоном. Однако каждое устройство предъявляет свои требования к формату списка контактов, и форматы телефонных книг в каждом устройстве разные. При необходимости модно было бы работать с двумя списками контактов – сначала добавлять новую запись в обе телефонные книги, а затем редактировать обе книги при изменении информации о контактах. Конечно, более предпочтительным является вариант, когда оба телефона получают данные из одного и того же источника, позволяющего вносить изменения только в одном месте. Что ж, если вы подключены к Интернету или интрасети, это не проблема. В этой статье я покажу, как одна база данных MySQL может предоставлять информацию о контактах двум различным устройствам: стационарному VoIP-телефону семейства snom 300 и мобильному смартфону (в нашем примере используется Nokia E71)

Часто используемые сокращения:

  • HTML: Hypertext Markup Language – язык разметки гипертекстовых документов
  • HTTP: Hypertext Transfer Protocol – протокол передачи гипертекста
  • LAN: Local area network – локальная сеть
  • LDAP: Lightweight Directory Access Protocol – облегченный протокол доступа к каталогам
  • SQL: Structured Query Language – язык структурированных запросов
  • VoIP: Voice over IP – передача голоса по IP-протоколу
  • XML: Extensible Markup Language – расширяемый язык разметки
Семейство snom 300 представляет собой линейку надежных VoIP-телефонов с широким набором важных офисных функций, таких как удержание, переадресация вызова и конференц-связь. Хотя в этих телефонах не реализована поддержка получения данных с LDAP-сервера, в них есть мини-браузер, позволяющий читать HTML-код. Кроме того, он умеет выводить текст на дисплей телефона в формате, позволяющем инициировать телефонный вызов.
В листинге 1 приведен пример XML-формата телефонной книги, используемого мини-браузером snom.

Листинг 1. Пример XML-кода для мини-браузера snom
   PhoneList - Snom        Friend, First     555-456-7890           Person, Second     555-654-0987           F1          F_ENTER     

В этом листинге корневой элемент SnomIPPhoneDirectory имеет три дочерних элемента: Title, DirectoryEntry иSoftKeyItem. Заголовок (Title) отображается в верхней части дисплея телефона и остается на месте при прокрутке. За ним следуют записи каталога (DirectoryEntry); каждая запись занимает одну строку, и эти строки можно прокручивать. Программируемые клавиши (SoftKeyItem) относятся к четырем кнопкам, расположенным под дисплеем. Эти кнопки могут выполнять различные функции, например, инициализировать вызов абонента, чье имя подсвечено на дисплее. В этом примере имеются две записи каталога, состоящие из отображаемого имени абонента и его телефонного номера, используемого для набора, и активируется только одна кнопка – F1, нажатие на которую инициирует набор телефонного номера.
Nokia E71 - хороший пример современного смартфона. Он умеет соединяться с сотовыми и беспроводными локальными сетями, имеет встроенные SIP-клиент и Интернет-браузер и поддерживает голосовое управление.
Смартфон E71 поддерживает протокол WAP (Wireless Application Protocol – протокол беспроводной связи) версии 2.0 (не путайте WAP2 с протоколом защиты беспроводных сетей WPA2). Это означает, что E71 может считывать XML-файлы, осуществляющие внутренние взаимодействия с его специальными функциями, например, открытие окна для начала телефонного вызова. 
В листинге 2 приведен пример требуемого смартфону содержимого в формате WAP2/XML. В этом примере используются те же самые записи каталога (два вымышленных контакта), что и в листинге 1.

Листинг 2. Пример WAP2 XML
        Tel (WTAI): Friend, First
Tel (WTAI): Person, Second     

Протокол WAP2 требует, чтобы данные предоставлялись в виде "колоды карт". Корневой элемент включает в себя один дочерний элемент (или страницу) , содержащий две строки, разделенных тегом перевода строки. Заголовок страницы указан в атрибуте корневого элемента. Телефонные номера указаны в виде ссылок () внутри атрибута, использующего протокол WTAI (Wireless Telephony Applications Interface – протокол приложений беспроводной телефонии, . При открытии страницы в браузере телефона и нажатии на ссылку с телефонным номером появляется всплывающее окно с запросом подтверждения вызова; на этом этапе телефон выбирает маршрут вызова – беспроводная локальная сеть или другая доступная услуга связи.
Поскольку в смартфоне не предусмотрена поддержка протокола LDAP, а стационарный телефон не умеет работать с WAP2, то может показаться, что между ними мало общего. Тем не менее можно найти общее решение, используя гибкость XML и командные сценарии. Можно было бы попытаться найти способ синхронизировать адресную книгу смартфона с LDAP-сервером, но сделать это было бы не так просто, как при использовании прямого динамического доступа к информации. К счастью, несмотря на то, что формат XML может различаться в двух разных схемах, сами данные остаются неизменными.
Поскольку оба устройства могут подключаться доступ к Интернету, одно из возможных решений, позволяющих использовать общую адресную книгу, такое: вся информация хранится в базе данных, а для генерации XML-файла и передачи его в браузер подходящего устройства используется механизм сценариев. Если вы знаете, какое устройство обращается к сценарию, то можно сгенерировать и отправить соответствующий ответ для этого устройства. Кроме того, сценарий может управлять доступом и отфильтровывать отправляемую информацию по мере необходимости.
Данные могут храниться в самых различных форматах и извлекаться по мере необходимости. Для хранения данных можно использовать PostgreSQL, XML, простой текст, IBM® DB2® и т. д. В листинге 3 приведен пример схемы базы данных MySQL.

Листинг 3. Схема базы данных для нашего примера
CREATE TABLE IF NOT EXISTS 'mycontacts' (   'id' int(11) NOT NULL auto_increment,   'firstName' varchar(30) default NULL,   'lastName' varchar(30) default NULL,   'number' varchar(20) default NULL,   PRIMARY KEY  ('id') ) ENGINE=MyISAM  DEFAULT CHARSET=latin1 ; 

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

Листинг 4. Базовый код генератора вывода
query($query);     $num = $result->num_rows;     $i = 0;     while ($row = $result->fetch_array()) {            $myarr[$i]['first']=$row["firstName"];         $myarr[$i]['last']=$row["lastName"];         $myarr[$i]['phone']=$row["number"];         $i++;     }     $mysqli->close();     switch ($dev) {       case 'snom':         echo mysnom($myarr);       break;       case 'noki':         echo mynoki($myarr);       break;       default:         echo mytest($myarr);       break;     } function mytest($myarr) {   $cont = "Header\n";   foreach ($myarr as $a) {     $cont .= " ".$a['first']." ".$a['last']." ".$a['phone']."\n";   }   $cont .= "Footer\n";   return $cont; } function show_err($dev,$msg) {   die($msg); } ?> 

Код сценария начинается с определения переменных, используемых для доступа к базе данных, установки подключения и возврата результирующего набора данных или сообщения о невозможности подключения к БД. Далее в цикле whileпоследовательно считываются все записи результирующего набора и информация сохраняется в массив для последующего использования. Поскольку начальным значением переменной устройства $dev является строка нулевой длины, то при выполнении оператора switch происходит переход в секцию default и выполняется вызов функцииmytest(). Эта функция выводит заголовок, содержимое массива и нижний колонтитул в виде обычного текста.
В этом сценарии обрабатывается лишь одна ошибка – неудачное подключение к базе данных. Вы можете написать дополнительный код для обработки других ошибок – например, успешного подключения к пустой базе данных. Для отслеживания и обработки этих событий можно использовать подобные вызовы функции show_err().
Теперь у нас имеется все необходимое для того, чтобы научить наш сценарий работать с разными типами устройств. В операторе switch имеются условия для двух телефонов, но функции еще не определены. Наша задача состоит в том, чтобы сгенерировать вывод для других устройств в требуемом XML-формате.
Если вы проанализируете листинг 1, то поймете, что функции из листинга 5 добавляют функциональность, необходимую для работы со стационарным VoIP-телефоном.

Листинг 5. Функции для работы с мини-браузером стационарного телефона
function mysnom($myarr) {     $cont = "    MySQL Directory";   foreach ($myarr as $a) {     $cont .= "        ".$a['first']." ".$a['last']."     ".$a['phone']."   \n";   }   $cont .= "\n";   return $cont; } function show_err($dev,$msg) {   switch ($dev) {     case 'snom':       echo "     $msg     ";     break;     default:       echo $msg;     break;   }   die(); } 

В отличие от листинга 4, в котором вывод генерируется в виде обычного текста, функции, добавленные в листинге 5, упаковывают данные в формат, используемый мини-браузером телефона. В сценарий была добавлена новая функцияmysnom(), а функция show_err() была заменена. Мини-браузер не умеет отображать простой текст (в этом случае он просто ничего не делает), поэтому как обычные данные, так и сообщения об ошибках необходимо выводить в формате XML. Поскольку вы пользуетесь телефоном, то именно на нем должны отображаться сообщения об ошибках. В случае невозможности подключения к базе данных сценарий отправляет сообщение об ошибке на телефон. В случае успешного подключения на телефон отправляется корневой элемент, а затем начинает выполняться цикл while. В этом цикле каждая запись упаковывается в свои собственные теги элемента каталога, после чего начинается настройка кнопок телефона. Поскольку телефон имеет всего четыре функциональные кнопки, вряд ли стоит хранить их значения в базе данных. И, наконец, последняя часть кода закрывает корневой элемент.
Функции из листинга 5 срабатывают в том случае, если переменная $dev определена в начале кода следующим образом:
$dev = "snom"; 

В случае использования смартфона Nokia необходимо получить вывод в XML-формате WAP2 с учетом WTAI. Этот код представлен в листинге 6.

Листинг 6. Функция для работы с протоколом WAP2 мобильного смартфона
function mynoki($myarr) {   $cont = "  \n   \n";   foreach ($myarr as $a) {     $cont .= "\nTel (WTAI):        ".$a['last']." ".$a['first']."
";   }   $cont .= "\n";   return $cont; } 

Этот код также преобразует данные в требуемый XML-формат, используемый в телефонах Nokia. В этом случае текст сообщения о неудачном подключении к БД не упаковывается в какие-либо XML-теги, поскольку телефон может отображать простой текст без каких-либо дополнительных требований. Когда все записи телефонной книги окажутся отображены на экране телефона, сценарий отправляет информацию XML и DOCTYPE, а также открывающие теги элементов и , после чего начинается цикл foreach, в котором к каждой строке результирующего набора добавляется необходимая информация протокола WTAI. Наконец, последняя часть кода закрывает элементы и.
Функция из листинга 6 срабатывает в том случае, если переменная $dev определена в начале кода следующим образом:
$dev = "noki"; 

Заметим, что предлагаемый вариант списка контактов для смартфона Nokia E71 не является полной заменой встроенной телефонной книги, которая, являясь частью системы, несомненно имеет ряд преимуществ, обеспечивающих ее тесное взаимодействие с остальными приложениями смартфона. Тем не менее список контактов для встроенной телефонной книги также можно сгенерировать на основе базы данных MySQL, используя тот же самый подход; отличие будет заключаться в том, что промежуточный вывод, который затем будет импортирован в телефон, необходимо генерировать в формате vCard (VCF). 
Последняя наша задача состоит в том, чтобы сообщить сценарию, в каком формате требуется получить данные. Для этого можно воспользоваться разными способами, одним из которых является отправка информации GET в строке HTTP-запроса. Представьте, что вы отправляете следующий запрос, в котором явно указаны устройство и пользователь:
http://www.myserver.tld/phonebook/myscript.php?device=snom&user=jim 

Итак, в листинге 7 представлен полностью готовый сценарий, который анализирует строку запроса и инициализирует переменные в соответствии с полученной информацией во время выполнения.

Листинг 7. Определение устройства
query($query);     $num = $result->num_rows;     $i = 0;     while ($row = $result->fetch_array()) {            $myarr[$i]['first']=$row["firstName"];         $myarr[$i]['last']=$row["lastName"];         $myarr[$i]['phone']=$row["number"];         $i++;     }     $mysqli->close();     switch ($dev) {       case 'snom':         echo mysnom($myarr);       break;       case 'noki':         echo mynoki($myarr);       break;       default:         echo mytest($myarr);       break;     } function mytest($myarr) {   $cont = "Header\n";   foreach ($myarr as $a) {     $cont .= " ".$a['first']." ".$a['last']." ".$a['phone']."\n";   }   $cont .= "Footer\n";   return $cont; } function mynoki($myarr) {   $cont = "  \n   \n";   foreach ($myarr as $a) {     $cont .= "\nTel (WTAI):        ".$a['last']." ".$a['first']."
";   }     $cont .= "\n";   return $cont; } function mysnom($myarr) {     $cont = "    MySQL Directory";   foreach ($myarr as $a) {     $cont .= "        ".$a['first']." ".$a['last']."     ".$a['phone']."   \n";   }   $cont .= "\n";   return $cont; } function show_err($dev,$msg) {   switch ($dev) {     case 'snom':       echo "     $msg     ";     break;     default:       echo $msg;     break;   }   die(); } ?> 

Этот код объединяет код из листингов 4, 5 и 6 и содержит дополнительную проверку пользователя; если пользователю не разрешен доступ к информации, то выполнение сценария останавливается. В противном случае на основании строки запроса определяется устройство, для которого в соответствии с правилами генерируются выходные данные.
Каждое устройство отправляет свои собственные запрос и строку запроса к базе данных и получает быстрый ответ в том формате, с которым оно работает.
Общий список контактов можно использовать и на других платформах, по-разному генерируя вывод XML. Функция для телефонов Nokia должна работать с любым устройством с поддержкой WAP 2.0. Более сложной может оказаться адаптация функции snom для использования на других телефонах, но если они работают с XML, то все, что вам нужно – это подобрать правильную схему. Вы можете изменять и расширять функциональность сценария так, как вам это нужно, используя для этого наиболее удобный для вас язык сценариев.


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