Ajax 入門(mén)
Ajax
作為一種創(chuàng)建功能全面的 Web 應(yīng)用程序的優(yōu)秀方法,借助 XML 的力量將數(shù)據(jù)表單和功能分離,打破了 Web 瀏覽器的規(guī)則和限制,使
Internet 的整體速度獲得了提升。Ajax 的主要限制包括在 JavaScript 中處理 XML。XML
的優(yōu)勢(shì)同樣也使自己變得十分復(fù)雜。在您確保了 XML 文檔的格式正確無(wú)誤并且設(shè)置了錯(cuò)誤處理之后,仍必須把 XML 置入某種 JavaScript
可用的對(duì)象中。把 XML 整合到應(yīng)用程序中以供使用并不像聽(tīng)起來(lái)那么簡(jiǎn)單。
由于 XML 不是 JavaScript 本來(lái)就有的,因此我們最好使用 XML 的固有語(yǔ)言,例如 PHP 和被轉(zhuǎn)換為 JavaScript 的固有格式的簡(jiǎn)單數(shù)據(jù)
。
我們遇到的另一個(gè)問(wèn)題是不總是希望或需要在把數(shù)據(jù)裝入 Ajax 應(yīng)用程序之前將數(shù)據(jù)轉(zhuǎn)換為
XML。然而,在 Ajax 開(kāi)發(fā)人員可以使用我們提供的數(shù)據(jù)之前,我們需要遵守標(biāo)準(zhǔn)。一旦我們?cè)?PHP
代碼中創(chuàng)建了對(duì)象,我們可以將其序列化,并導(dǎo)出到應(yīng)用程序的 Ajax 部分中,處理并取回。
JSON
JSON
是一項(xiàng)旨在允許中間件創(chuàng)建使用 JavaScript 固有格式的對(duì)象的協(xié)議。它最強(qiáng)大的屬性是它是一種輕量級(jí)協(xié)議。簡(jiǎn)單處理 RSS 聚合或
recipe 列表時(shí),您不需要在 JavaScript 中使用 XML 的全部功能。不需要驗(yàn)證格式或確保嚴(yán)格的數(shù)據(jù)鍵入。我們可以跳過(guò)與處理
XML 相關(guān)的大量工作,即使術(shù)語(yǔ) Ajax 包括 XML。為了編寫(xiě)更簡(jiǎn)練的代碼,您可以使用 JSON 來(lái)簡(jiǎn)化過(guò)程。讓我們來(lái)看一個(gè)顯示來(lái)自 RSS 摘要數(shù)據(jù)庫(kù)應(yīng)用程序的數(shù)據(jù)的簡(jiǎn)單 XML 文檔示例。
清單 1. XML 格式示例
Listing 1 - XML Format Example <?xml version="1.0" ?> <root> <feed> <id>21</id> <url>www.blah.com/story1.html</url> <title>JSON is sweeping AJAX world</title> <viewed>FALSE</viewed> </feed> <feed > <id>22</id> <url> www.blah.com/story2.html</url> <title>JSON is great</title> <viewed>FALSE</viewed> </feed> </root>
|
要獲得此 XML
文檔,我們需要訪(fǎng)問(wèn)數(shù)據(jù)庫(kù),取出相關(guān)數(shù)據(jù),并使用 PHP 在此 XML 文檔中設(shè)定格式。雖然 Ajax 可以利用
XML,但是在大多數(shù)情況下都是不必要的??刂平Y(jié)構(gòu)所需的負(fù)載帶寬量對(duì)于只需共享一些鏈接的簡(jiǎn)單應(yīng)用程序來(lái)說(shuō)完全沒(méi)必要。此外,我們必須遞歸處理
MySQL 結(jié)果,刪除非法字符以及逐位構(gòu)建我們的 XML 文檔。
JSON 在這種情況下將提供幫助,因?yàn)槲覀兛梢允褂?json_encode() 把任何 PHP 對(duì)象序列化,使該對(duì)象轉(zhuǎn)換為 JSON 協(xié)議字符串,以供 Ajax 應(yīng)用程序讀取。這要比創(chuàng)建 XML 文檔便捷得多,因?yàn)槲覀冎恍璋?MySQL 結(jié)果直接傳給函數(shù)。由于 MySQL 結(jié)果是以聯(lián)合數(shù)組的形式傳入的,因此沒(méi)有任何中間步驟。
讓我們來(lái)看一看如果把以上 XML 文檔轉(zhuǎn)換為 JSON 對(duì)象會(huì)發(fā)生什么情況(參見(jiàn)清單 2)。目前,數(shù)據(jù)庫(kù)和數(shù)據(jù)格式都是任意的;我們將在稍后的部分中了解它們的實(shí)際情況。
清單 2. 把 XML 轉(zhuǎn)換為 JSON 的 PHP 示例
<?php //we assume that $results is the result of an SQL query but we will construct it now $results = array("21" => array("url" => "www.blah.com/story1.html", "title" => "JSON is sweeping AJAX world", "viewed" => FALSE), "22" => array("url" => "www.blah.com/story2.html", "title" => "JSON is great", "viewed" => FALSE)); //we now have a populated array object in $results resembling a possible MySQL result
$jsonObject = json_encode($results); echo $jsonObject; ?>
|
全部都能理解么?結(jié)果沒(méi)有使用遞歸。沒(méi)有添加標(biāo)記。只需將其傳入 json_encode() 函數(shù),然后它將從另一端作為 JSON 序列化對(duì)象傳出。參見(jiàn)清單 3 以查看新對(duì)象。
清單 3. JSON 序列化的 XML 對(duì)象示例
{"21":{"url":"www.blah.com\/story1.html","title":"JSON is sweeping AJAX world","viewed":false},"22":{"url":"www.blah.com\/story2.html", "title":"JSON is great","viewed":false}}
|
我們有了一個(gè)包含數(shù)組對(duì)象并且以 JSON 格式序列化的字符串。關(guān)于此字符串需要注意幾點(diǎn):encode 函數(shù)已經(jīng)自動(dòng)把正斜杠轉(zhuǎn)義為反斜杠,并且變量類(lèi)型都是可以標(biāo)識(shí)的,這取決于我們是否使用引號(hào)。由于數(shù)組中的 ID 號(hào)都使用了引號(hào),因此那些 ID 號(hào)都被識(shí)別為字符串。布爾型 false 元素都被保留為布爾型。
現(xiàn)在我們已經(jīng)序列化了對(duì)象,我們可以在 Ajax 應(yīng)用程序的任意數(shù)目的 JSON 函數(shù)中使用它。
編碼和解碼
有兩個(gè)函數(shù)用于 JSON:encode 和 decode 。像您想象的一樣,第一個(gè)函數(shù)將把任意類(lèi)型的數(shù)據(jù)對(duì)象轉(zhuǎn)換為一組序列化數(shù)據(jù),以供 JavaScript 處理。第二個(gè)函數(shù)將把序列化數(shù)據(jù)解碼,并將其轉(zhuǎn)換為基本 PHP 對(duì)象或聯(lián)合數(shù)組。我們已經(jīng)見(jiàn)過(guò)使用 json_encode() 的示例,因此讓我們來(lái)看一看 json_decode() 。
清單 4. json_decode() 的示例
<?php $jsonObject = ‘{"21":{"url":"www.blah.com\/story1.html","title":"JSON is sweeping AJAX world","viewed":false},"22":{"url":"www.blah.com\/story2.html","title":"JSON is great","viewed":false}}‘;
$decodedObject = json_decode($jsonObject); $decodedArray = json_decode($jsonObject, true);
print_r($decodedObject); echo "<br><br>"; print_r($decodedArray);
?>
|
如上,我們有一個(gè) PHP 腳本,該腳本將獲取 $jsonObject 并將其解碼回 PHP 固有對(duì)象。我們進(jìn)行了兩次解碼。第一次,使用未經(jīng)修改的用法,這將得到 stdClass 的對(duì)象;第二次,使用布爾型參數(shù)來(lái)創(chuàng)建聯(lián)合數(shù)組。
清單 5. 清單 4 的輸出
stdClass Object ( [21] => stdClass Object ( [url] => www.blah.com/story1.html [title] => JSON is sweeping AJAX world [viewed] => ) [22] => stdClass Object ( [url] => www.blah.com/story2.html [title] => JSON is great [viewed] => ) ) Array ( [21] => Array ( [url] => www.blah.com/story1.html [title] => JSON is sweeping AJAX world [viewed] => ) [22] => Array ( [url] => www.blah.com/story2.html [title] => JSON is great [viewed] => ) )
|
我們看到兩個(gè)對(duì)象,使用 print_r() 列出。
從數(shù)據(jù)庫(kù)到 JSON
在
建議的 Ajax 應(yīng)用程序中,我們的項(xiàng)目經(jīng)理希望使用來(lái)自另一個(gè)應(yīng)用程序提供的數(shù)據(jù)庫(kù)的數(shù)據(jù)。存儲(chǔ) Web 服務(wù)器的 MySQL 數(shù)據(jù)庫(kù)中選定
RSS 摘要結(jié)果的 RSS 聚合器將經(jīng)常檢查并更新 RSS。要閱讀 RSS,我們的應(yīng)用程序?qū)⒁笫褂?Ajax
接口。作為專(zhuān)業(yè)的后端程序員,我們將專(zhuān)注于從數(shù)據(jù)庫(kù)中獲得數(shù)據(jù),并將其轉(zhuǎn)為 JSON 格式。我們將把 Ajax 留給專(zhuān)家,但是我們必須把 Ajax
準(zhǔn)備好以供專(zhuān)家們處理。
首先,我們將設(shè)置 MySQL 數(shù)據(jù)庫(kù)來(lái)存儲(chǔ) RSS 摘要信息,然后插入若干條記錄以準(zhǔn)備開(kāi)始。然后,我們將編寫(xiě)一個(gè) PHP 腳本,該腳本將進(jìn)入數(shù)據(jù)庫(kù)并為基于 JSON 的應(yīng)用程序檢索一些記錄以供使用。
設(shè)置
我
們需要設(shè)置 MySQL 數(shù)據(jù)庫(kù)并插入一些簡(jiǎn)單記錄以供我們提取。為便于使用示例,我們將使用數(shù)據(jù)庫(kù)名 “RSS_AGG”(參見(jiàn)清單
6)。由于大多數(shù)主要關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng)(Relational Database Management System,RDBMS)從一開(kāi)始就支持
PHP,因此在選擇數(shù)據(jù)庫(kù)時(shí),PHP 具有極大的靈活性。一些 RDBMS 不支持 PHP,但是很多這樣的 RDBMS 可以通過(guò)抽象類(lèi)或擴(kuò)展來(lái)提供
PHP 支持。我使用了 MySQL,但是可以任意采用這段代碼來(lái)支持您選擇的數(shù)據(jù)庫(kù)。
清單 6. feeds 表和兩條記錄的 SQL
CREATE TABLE ‘feeds‘ ( ‘id‘ int(11) NOT NULL auto_increment, ‘url‘ text NOT NULL, ‘title‘ text NOT NULL, ‘viewed‘ tinyint(1) NOT NULL, PRIMARY KEY (‘id‘) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
INSERT INTO ‘feeds‘ (‘id‘, ‘url‘, ‘title‘, ‘viewed‘) VALUES (1, ‘www.blah.com/story1.html‘, ‘JSON is sweeping AJAX world‘, 0), (2, ‘www.blah.com/story2.html‘, ‘JSON is great‘, 0);
|
我們現(xiàn)在有一個(gè)可以通過(guò) PHP 腳本訪(fǎng)問(wèn)的數(shù)據(jù)庫(kù)。至于所有數(shù)據(jù)庫(kù)交互,我們需要設(shè)置數(shù)據(jù)庫(kù)連接并提取數(shù)據(jù)。
清單 7. output.php
<?php
$username="username"; $password="password"; $database="rss_agg"; $sql="SELECT * FROM `feeds`";
mysql_connect(localhost, $username, $password); mysql_select_db($database) or die("Unable to select database"); $result = mysql_query($sql);
mysql_close(); ?>
|
在輸出腳本的開(kāi)頭,我們只是創(chuàng)建變量來(lái)存儲(chǔ)可以訪(fǎng)問(wèn)位于本地主機(jī)的數(shù)據(jù)庫(kù)的用戶(hù)名和密碼。我們選擇了數(shù)據(jù)庫(kù),命名為 rss_agg,并編寫(xiě)了一條十分簡(jiǎn)單的 SELECT
語(yǔ)句從 feeds
表中檢索所有記錄。接下來(lái)的三行將使用連接憑證來(lái)發(fā)起一個(gè)與數(shù)據(jù)庫(kù)的連接,然后選擇數(shù)據(jù)庫(kù)。如果出于某種原因這個(gè)過(guò)程沒(méi)有發(fā)生,我們將看到
“Unable to select database” 結(jié)果。最后,我們將檢索 SQL 語(yǔ)句的結(jié)果并關(guān)閉數(shù)據(jù)庫(kù)連接。
編碼為 JSON
需要先把 MySQL 結(jié)果轉(zhuǎn)換為可用的 PHP 對(duì)象,然后才能把 MySQL 結(jié)果轉(zhuǎn)換為 JSON 字符串。我們可以通過(guò)把它轉(zhuǎn)為一個(gè)數(shù)組來(lái)完成以上操作。
清單 8. 帶有 JSON 代碼的 output.php
<?php $username="root"; $password=""; $database="rss_agg"; $sql="SELECT * FROM `feeds`"; $encodable = array();
mysql_connect(localhost, $username, $password); mysql_select_db($database) or die("Unable to select database"); $result = mysql_query($sql);
while($obj = mysql_fetch_object($result)) { $encodable[] = $obj; }
$encoded = json_encode($encodable);
echo $encoded;
mysql_close(); ?>
|
我們已經(jīng)創(chuàng)建了一個(gè)數(shù)組對(duì)象來(lái)存儲(chǔ) json_encode() 可以讀取和轉(zhuǎn)換為 JSON 字符串格式的結(jié)果信息。while 語(yǔ)句將逐個(gè)遍歷結(jié)果查詢(xún)的每個(gè)元素并逐行構(gòu)建 $encodable 數(shù)組。此對(duì)象完成后,我們只需通過(guò) json_encode() 運(yùn)行它并生成 $encoded 對(duì)象?,F(xiàn)在,可以將此信息回轉(zhuǎn)給瀏覽器,用來(lái)自對(duì)象的數(shù)據(jù)來(lái)響應(yīng)請(qǐng)求的 JavaScript。請(qǐng)求 JavaScript 應(yīng)用程序現(xiàn)在有一個(gè)完全相同的 PHP 對(duì)象副本,并使用 JavaScript 天生就能理解的方法列舉了該副本。
結(jié)束語(yǔ)
JSON
是一種有用的、輕量級(jí)協(xié)議,現(xiàn)在可用于 PHP V5.2,它可以輕松地實(shí)現(xiàn)從 PHP 應(yīng)用程序中提取出數(shù)據(jù),并將其放入 Ajax
應(yīng)用程序的過(guò)程。相應(yīng)地,PHP 中的 JSON
同樣也是輕量級(jí)且十分有用的,只包含兩個(gè)易于使用的函數(shù)。使用這些函數(shù),我們可以轉(zhuǎn)換和導(dǎo)出對(duì)象結(jié)構(gòu),還可以使用 json_encode() 使來(lái)自 PHP 數(shù)據(jù)庫(kù)連接的數(shù)據(jù)可用于 Ajax 應(yīng)用程序。在 Ajax 應(yīng)用程序中處理完數(shù)據(jù)后,可以將數(shù)據(jù)返回 PHP 腳本并用 json_decode() 重新創(chuàng)建可用的對(duì)象數(shù)據(jù)結(jié)構(gòu)。當(dāng)把數(shù)據(jù)返回到 PHP 后,我們可以將其存儲(chǔ)到數(shù)據(jù)庫(kù)中,或使用 PHP 提供的眾多選擇中的任何其他數(shù)據(jù)處理方法。
參考資料
學(xué)習(xí)
|