用php编写室友通讯录_使用 XML 和 PHP 创建一个更具适应性的电话簿和通讯录
使用 XML 和 PHP 創(chuàng)建一個(gè)更具適應(yīng)性的電話簿和通訊錄
使用 XML 為您的電話提供一個(gè)一致的通訊錄
Colin Beckingham
2011 年 5 月 09 日發(fā)布
您需要與聯(lián)系人隨時(shí)保持聯(lián)系 — 即使在出差途中。在辦公室,可以使用您的桌面 VoIP 電話;出差途中,可以使用智能電話。但每臺(tái)設(shè)備都要求其電話列表采用一種特殊格式,每臺(tái)設(shè)備都有自己的、格式與眾不同的通訊錄或電話簿。如果有必要,可能需要輸入您的所有聯(lián)系人兩次 — 每個(gè)通訊錄一次 — 每次變更聯(lián)系人時(shí),都需要同時(shí)在兩個(gè)列表中進(jìn)行更改。毫無疑問,您肯定希望這兩部電話從同一個(gè)后端數(shù)據(jù)源獲取數(shù)據(jù),這樣您就只需在一個(gè)地方編輯姓名和電話號(hào)碼。這不成問題:只要能訪問互聯(lián)網(wǎng)或內(nèi)聯(lián)網(wǎng)。在本文中,了解如何使用一個(gè) MySQL 數(shù)據(jù)庫中的數(shù)據(jù)向兩個(gè)完全不同的設(shè)備提供聯(lián)系信息:一部通過 snom 300 系列設(shè)備標(biāo)識(shí)的 VoIP 電話和一個(gè)采用 Nokia E71 設(shè)備形狀的智能電話(參見 參考資料 中的鏈接)。
桌面設(shè)備:snom 300 系列
常用縮略詞HTML:超文本標(biāo)記語言
HTTP:超文本傳輸協(xié)議
LAN:局域網(wǎng)
LDAP:輕量級(jí)目錄訪問協(xié)議
SQL:結(jié)構(gòu)化查詢語言
VoIP:IP 語音傳輸
XML:可擴(kuò)展標(biāo)記語言
snom 300 系列提供優(yōu)質(zhì)穩(wěn)定的 VoIP 電話,這些電話擁有廣泛的辦公功能,比如等待、轉(zhuǎn)接和電話會(huì)議。這類電話的確擁有對(duì)來自 LDAP 服務(wù)器的數(shù)據(jù)提要的原生支持,它還擁有一個(gè)能閱讀 HTML 的微型瀏覽器(參見 參考資料)。它甚至能以一種能夠觸發(fā)電話呼叫的格式在電話屏幕上顯示文本。
清單 1 展示 snom 微型瀏覽器需要(特別是在電話簿上下文中)的 XML 格式的示例。
清單 1. snom XML 微型瀏覽器示例<?xml version="1.0" encoding="UTF-8"?>
PhoneList - SnomFriend, First
555-456-7890
Person, Second
555-654-0987
F1
Dial
F_ENTER
在這段代碼中,根元素 SnomIPPhoneDirectory 擁有 3 個(gè)不同子元素:Title、DirectoryEntry 和 SoftKeyItem。標(biāo)題位于電話顯示的頂部,滾動(dòng)過程中不間斷顯示。標(biāo)題下方是目錄條目 — 每行一個(gè)條目 — 且能夠滾動(dòng)。這些軟鍵項(xiàng)目關(guān)聯(lián)到顯示下方的 4 個(gè)按鈕。這些能執(zhí)行一些功能,比如對(duì)當(dāng)前突出顯示的目錄條目發(fā)起一個(gè)呼叫。這個(gè)示例中的數(shù)據(jù)包含兩個(gè)電話號(hào)碼條目:一個(gè)顯示姓名和一個(gè)用于撥號(hào)的號(hào)碼。它只激活一個(gè)按鈕:按下 F1 按鈕,電話就開始撥號(hào)。
旅行設(shè)備:Nokia E71 智能電話
Nokia E71 設(shè)備是一個(gè)典型現(xiàn)代智能電話示例。它能夠連接無線 WAN 或移動(dòng)電話服務(wù),擁有一個(gè) Session Initiation Protocol (SIP) 客戶端,能使用自己的本機(jī)瀏覽器瀏覽 Internet,并以移動(dòng)方式管理語音通信。
E71 設(shè)備支持 Wireless Application Protocol (WAP) 版本 2.0(WAP2 — 參見 參考資料)— 不要與 Wi-Fi Protected Access II (WPA2) 功能混淆。這意味著它能閱讀 XML 格式文件,這類文件在電話內(nèi)部與各種專業(yè)功能通信,比如打開一個(gè)窗口來發(fā)起一次呼叫。
清單 2 展示了這種智能電話需要的 WAP2/XML 格式內(nèi)容示例。這個(gè)示例使用 清單 1 中顯示的那兩個(gè)虛構(gòu)條目。
清單 2. WAP2 XML 示例<?xml version="1.0"?>
/p>
"http://www.wapforum.org/DTD/wml_1.1.xml" >
Tel (WTAI): Friend, First
Tel (WTAI): Person, Second
WAP2 要求以卡片組的形式顯示數(shù)據(jù)。根元素 擁有一個(gè)子元素 (或頁面),該子元素有兩行,通過一個(gè)換行符分隔。這個(gè)頁面的標(biāo)題在這個(gè)根元素的一個(gè)屬性中列示。這些電話號(hào)碼在一些錨點(diǎn)元素(即 )中列示,有一個(gè) 屬性使用 Wireless Telephony Applications Interface(WTAI — 參見 參考資料)。當(dāng)您打開電話的瀏覽器中的頁面并單擊一個(gè)電話鏈接時(shí),一個(gè)窗口將彈出并詢問您是否要呼叫這個(gè)號(hào)碼,這時(shí)電話找到一條路徑來路由呼叫 — 無論是通過一條無線 LAN 還是使用另一個(gè)電話訂閱。
由于智能電話沒有處理 LDAP 的原生能力且桌面電話不能處理 WAP2,它們似乎沒有什么共同點(diǎn)。但是,編寫腳本通過使用 XML 的適應(yīng)性提供了一種解決方案。您可能會(huì)找到一種方法,通過智能電話同步您的聯(lián)系人和 LDAP 服務(wù)器,但這種方法可能不如直接訪問信息那么簡捷。幸運(yùn)的是,盡管 XML 的格式在這兩種架構(gòu)之間可能會(huì)更改,但數(shù)據(jù)在根本上是相同的。
解決方案
鑒于這兩種設(shè)備均可隨時(shí)隨地訪問 Internet,實(shí)現(xiàn)一個(gè)通用電話簿的解決方案是將所有數(shù)據(jù)放置在一個(gè)數(shù)據(jù)庫中,然后使用一個(gè)腳本引擎生成一個(gè) XML 文件,并將其傳遞給您認(rèn)為最方便的設(shè)備瀏覽器。另外,這個(gè)腳本能根據(jù)需要控制訪問權(quán)并過濾要交付的信息。
數(shù)據(jù)庫
數(shù)據(jù)可以存儲(chǔ)為各種格式并根據(jù)需要提取,包括 PostgreSQL、XML、純文本、IBM? DB2? 等。清單 3 展示了一個(gè) MySQL 樣例架構(gòu)。
清單 3. 示例數(shù)據(jù)庫架構(gòu)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 ;
這個(gè)表只包含 4 個(gè)字段 — 一個(gè) ID、姓名、電話號(hào)碼 — 以及一個(gè)索引。該架構(gòu)顯示了所需要信息的關(guān)鍵組成部分??梢愿鶕?jù)需要進(jìn)一步添加字段和索引??梢愿鶕?jù)需要采用您選擇的 LibreOffice Base 或 phpMyEdit(參見 參考資料)編輯器編輯數(shù)據(jù)內(nèi)容。
PHP 生成器
清單 4 展示了一個(gè)從后端獲取數(shù)據(jù)并以純文本格式顯示輸出的基本腳本。此時(shí),您只是測試腳本,確保它返回合理的數(shù)據(jù)。
清單 4. 基本數(shù)據(jù)庫生成器<?php
$dev = "";
$db_host = "your.database.server";
$db_user = "your_user";
$db_pass = "your_password";
$db_name = "your_database";
$mysqli = new mysqli($db_host, $db_user, $db_pass, $db_name);
if (mysqli_connect_errno()) show_err($dev,"Could not connect to database");
$query = "SELECT * FROM mycontacts order by lastName asc";
$result = $mysqli->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);
}
?>
這段代碼首先定義用于訪問數(shù)據(jù)庫的變量,打開一個(gè)連接,返回一個(gè)結(jié)果集或一條錯(cuò)誤消息(如果不能連接到數(shù)據(jù)庫的話)。然后,一個(gè) while 循環(huán)迭代數(shù)據(jù)集,在一個(gè)方便的數(shù)組中存儲(chǔ)信息以便將來進(jìn)行顯示。由于設(shè)備變量 $dev 被初始化為一個(gè)長度為零的字符串,因此,當(dāng) switch 執(zhí)行時(shí),它將切換到默認(rèn)值并調(diào)用 mytest() 函數(shù)。這個(gè)函數(shù)將顯示一個(gè)簡單的標(biāo)題,寫出數(shù)組內(nèi)容,然后打印一個(gè)頁腳 — 全部采用純文本格式。
這個(gè)腳本只處理一個(gè)可能的錯(cuò)誤:數(shù)據(jù)庫連接故障。您應(yīng)計(jì)劃處理其他情況,比如成功連接到數(shù)據(jù)庫但發(fā)現(xiàn)一個(gè)空表。您可以使用 show_err()
函數(shù)調(diào)用之類的調(diào)用捕獲并處理這些情況。
大多數(shù)組件都已就緒,可以泛化這個(gè)腳本,處理其他設(shè)備類型。switch 擁有針對(duì)這兩種電話的情況,但它們的功能還不存在?,F(xiàn)在的問題是如何使輸出與其他目標(biāo)設(shè)備相關(guān),根據(jù)需要添加 XML 格式的細(xì)節(jié)。
桌面微型瀏覽器
對(duì)照 清單 1 中的示例,您將看到,清單 5 中的函數(shù)添加了必要的組件來處理桌面 VoIP 電話。
清單 5. 處理桌面微型瀏覽器的函數(shù)function mysnom($myarr) {
$cont = "<?xml version=\"1.0\"?>
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 "<?xml version=\"1.0\"?>
$msg
";
break;
default:
echo $msg;
break;
}
die();
}
對(duì)比 清單 5 和 清單 4,您會(huì)發(fā)現(xiàn),這些新函數(shù)并不回顯純文本,而是回顯微型瀏覽器預(yù)期的元素中封裝的數(shù)據(jù)。mysnom() 函數(shù)是腳本的一個(gè)新增函數(shù),show_err() 函數(shù)是一個(gè)替代函數(shù)。
微型瀏覽器不能顯示純文本:它什么也不做。因此,常規(guī)和異常輸出都需要 XML 輸出。由于您正在使用電話,因此電話也是錯(cuò)誤消息必須顯示的地方。如果出現(xiàn)數(shù)據(jù)庫連接故障,腳本將向電話報(bào)告錯(cuò)誤。如果成功連接,則在 while 循環(huán)開始之前,腳本應(yīng)聲明根元素。循環(huán)進(jìn)行時(shí),每條記錄都被封裝到記錄自己的目錄條目標(biāo)記中;循環(huán)完成后,按鈕的設(shè)置就開始了。由于只有 4 個(gè)按鈕,是否也需要在數(shù)據(jù)庫中對(duì)其進(jìn)行編碼還存在疑問。最后,代碼結(jié)束了根元素。
上述函數(shù)要正常工作,必須在代碼開頭按如下方式正確設(shè)置變量 $dev:$dev = "snom";
智能電話 WAP2
如果是 Nokia 電話,則需要提供一些輸出細(xì)節(jié),它們通過 WTAI 引用以 WAP2 格式向智能電話提供 XML。清單 6 顯示了相關(guān)代碼。
清單 6. 處理智能電話 WAP2 的函數(shù)function mynoki($myarr) {
$cont = "<?xml version=\"1.0\"?>
"-//WAPFORUM//DTD WML 1.1//EN\"
\"http://www.wapforum.org/DTD/wml_1.1.xml\" >
\n
\n";
foreach ($myarr as $a) {
$cont .= "\nTel (WTAI):
".$a['last']." ".$a['first']."
";
}
$cont .= "\n";
return $cont;
}
同樣,這段代碼向 Nokia 電話提供必要的 XML。如果出現(xiàn)數(shù)據(jù)庫連接錯(cuò)誤,文本輸出不需要封裝到任何標(biāo)記中,因?yàn)楹唵屋敵鰺o需任何標(biāo)記即可在此電話上正確顯示。當(dāng)電話簿條目被顯示時(shí),在循環(huán)開始之前,腳本發(fā)送 XML 和 DOCTYPE 信息,然后是 根元素和 元素的開始標(biāo)記。然后,循環(huán)開始,顯示封裝在 WTAI 信息中的每條記錄。最后,代碼結(jié)束 card 元素和 根元素。
上述函數(shù)要正常工作,必須在代碼開頭按如下方式正確設(shè)置變量 $dev:$dev = "noki";
請(qǐng)注意,Nokia E71 通訊錄的解決方案建議并不打算完全替代原有聯(lián)系人應(yīng)用程序,后者作為電話系統(tǒng)的一部分,肯定有一定優(yōu)點(diǎn),因此能與其他應(yīng)用程序形成緊密的內(nèi)部連接。但是,原有通訊錄可以使用同一流程從同一 MySQL 數(shù)據(jù)庫生成,但生成 vCard (VCF) 文件格式(參見 參考資料)的中間輸出,這樣便于導(dǎo)入電話。
檢測設(shè)備
這個(gè)問題的最后部分是讓腳本在運(yùn)行時(shí)了解需要哪種設(shè)備輸出??梢酝ㄟ^幾種方法完成此任務(wù),其中一種方法是在 HTTP 請(qǐng)求查詢字符串中發(fā)送 GET 信息。假設(shè)您發(fā)送以下請(qǐng)求,顯式聲明一個(gè)設(shè)備和一個(gè)用戶:http://www.myserver.tld/phonebook/myscript.php?device=snom&user=jim
然后,清單 7 中的最終腳本解析查詢字符串并在運(yùn)行時(shí)將信息插入腳本。
清單 7. 檢測設(shè)備<?php
if ($_GET['user'] != 'jim') show_err($dev,'Unauthorised access');
$dev = $_GET['device'];
$db_host = "your.database.server";
$db_user = "your_user";
$db_pass = "your_password";
$db_name = "your_database";
$mysqli = new mysqli($db_host, $db_user, $db_pass, $db_name);
if (mysqli_connect_errno()) show_err($dev,"Could not connect to database");
$query = "SELECT * FROM mycontacts order by lastName asc";
$result = $mysqli->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 = "<?xml version=\"1.0\"?>
"-//WAPFORUM//DTD WML 1.1//EN\"
\"http://www.wapforum.org/DTD/wml_1.1.xml\" >
\n
\n";
foreach ($myarr as $a) {
$cont .= "\nTel (WTAI):
".$a['last']." ".$a['first']."
";
}
$cont .= "\n";
return $cont;
}
function mysnom($myarr) {
$cont = "<?xml version=\"1.0\"?>
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 "<?xml version=\"1.0\"?>
$msg
";
break;
default:
echo $msg;
break;
}
die();
}
?>
這段代碼基本上是 清單 4 的重復(fù),只是添加了 清單 5 和 清單 6 中的函數(shù)。代碼首先進(jìn)行一個(gè)簡單檢查,了解用戶是誰,如果錯(cuò)誤的用戶企圖訪問信息,代碼將在控制條件下停止。然后,代碼從查詢字符串獲取設(shè)備,并根據(jù)指示完成輸出。
由于每部電話都向數(shù)據(jù)庫顯示自己的請(qǐng)求和查詢字符串,因此它們以設(shè)備可顯示的格式輕松快速地接收輸出。
結(jié)束語
您可以通過修改 XML 輸出在其他平臺(tái)上使用來自一個(gè)公共源的通訊錄。針對(duì) Nokia 的函數(shù)應(yīng)該適用于任何遵守 WAP 2.0 的電話。針對(duì)其他電話改編 snom 函數(shù)可能更加復(fù)雜,但如果使用 XML,那么您需要的只是正確的架構(gòu)。您可以使用任何方便的腳本語言、根據(jù)需要輕松維護(hù)和擴(kuò)展這個(gè)腳本。
相關(guān)主題snom VoIP 電話概覽:了解關(guān)于 snom 系列 VoIP 電話的更多信息。
snom 微型瀏覽器:了解 snom370、snom360、snom320、snom300 上的 V7 固件以及 snom820 和 snom870 上的 V8 固件支持的 XML 對(duì)象。
Nokia E71 智能電話:查看這種擁有 QWERTY 鍵盤的電話。
無線應(yīng)用程序協(xié)議(Wikipedia):閱讀一個(gè)關(guān)于用于移動(dòng)電話等小型移動(dòng)設(shè)備的常用 web 瀏覽器的優(yōu)秀條目。
用 PHP 編寫腳本:了解這種通用腳本語言的更多相關(guān)信息,這種語言尤其適合 web 開發(fā),可以嵌入到 HTML 中。
VCF 和 vCard 文件格式:了解用于電子商務(wù)卡的 vCard 文件格式標(biāo)準(zhǔn)的更多信息。
LibreOffice:了解這個(gè)面向 Windows、Macintosh 和 Linux 的 OpenSource 個(gè)人生產(chǎn)力套件。試用下面 6 個(gè)用于文檔生產(chǎn)和數(shù)據(jù)處理的應(yīng)用程序:Writer、Calc、Impress、Draw、Math 和 Base。
phpMyEdit:使用這個(gè)工具編寫一個(gè)簡單的調(diào)用程序,生成一些 PHP 代碼,以 HTML 格式顯示或編輯的 MySQL 表。
developerWorks XML 專區(qū):在 XML 專區(qū)獲取提高您的專業(yè)技能所需的資源。
XML 技術(shù)庫:訪問 developerWorks XML 專區(qū),獲得廣泛的技術(shù)文章和技巧、教程、標(biāo)準(zhǔn)和 IBM 紅皮書,并閱讀關(guān)于 XML 技巧 的更多信息。
developerWorks 技術(shù)活動(dòng) 和 網(wǎng)絡(luò)廣播:隨時(shí)關(guān)注這些活動(dòng)中的技術(shù)。
IBM 產(chǎn)品評(píng)估版:下載或 在線試用 IBM SOA Sandbox,并開始使用來自 DB2?、Lotus?、Rational?
、Tivoli? 和 WebSphere? 的應(yīng)用程序開發(fā)工具和中間件產(chǎn)品。
總結(jié)
以上是生活随笔為你收集整理的用php编写室友通讯录_使用 XML 和 PHP 创建一个更具适应性的电话簿和通讯录的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于深度学习的车型识别APP
- 下一篇: BCH编译码的matlab性能分析