一、我所理解的Ajax
Ajax是近幾年才出現的新技術,主要利用Javascript等技術實現使用者資料的隱式提交,並允許程式同步或者非同步處理伺服器發送的資料。和傳統的“submit”方式不同,資料的提交以及之後的處理不需要頁面的切換,為使用者在瀏覽器上提供了優秀的互動方式。
Ajax的實現無非是各瀏覽器廠商在瀏覽器中提供了一個公開的支援Ajax的組件。這個組件可以有Javascript調用,向伺服器端提交資料,接收伺服器端發送的資料。在接收資料後,頁面則可以通過指令碼處理、顯示資料,這些資料也就是一般意義上伺服器處理使用者提交資訊的結果。
從上文的意義理解,Ajax和PHP並沒有直接的關聯關係:Ajax在用戶端提交資料和接收結果;PHP在伺服器端處理資料,然而伺服器端啟動並執行程式並非一定是PHP,對Ajax來說,伺服器端是透明的。
二、使用Ajax實現使用者自訂查詢
1、程式說明
剛開始想在網上找一個教程來學習Ajax,也看到了關於xAjax的教程。xAjax是一個開源的PHP&Ajax架構,其首頁上提供了一個10分鐘學習的教程。但看了之後發現xAjax與PHP結合緊密,不符和我對Ajax的理解:前台html檔案,後台任意處理指令碼。所以放棄了使用xAjax寫第一個程式的想法,而使用了《Ajax開發精要——概念、案例與架構》(柯自聰編著,電子工業出版社,2006年)中一個簡單的範例架構實現Ajax程式。不過這種方法並不可取,因為在之後的實踐中出現了問題:查詢結果中有亂碼:)。
程式的功能還是一樣,使用者佈建主機、串連使用者、密碼、資料庫和SQL語句,程式串連資料庫,執行SQL語句,並將查詢結果返回給使用者。程式構成嚴格按照之前的理解,由兩個檔案組成:query.php和form3.html。其中query.php從之前的代碼截取,串連資料庫,執行SQL語句,以表格方式返回查詢結果。而form3.html在提供一個表單,並通過javascript調研Ajax組件提交使用者資料,接收處理結果,接收結果後將表格顯示在<span></span>中。
2、query.php
//抄襲之前的代碼
<table width="80%" border="1" cellpadding="0" cellspacing="1">
<?php
if (isset($_POST['action']) && $_POST['action'] == 'submitted') { //表單是否已經提交
$link = mysql_pconnect($_POST['host'], $_POST['username'], $_POST['password'])
or die("Could not connect: " . mysql_error()); //串連MYSQL
mysql_select_db($_POST['database'])
or die("Could not select database: " . mysql_error()); //選擇資料庫
$query = $_POST['sql'];
$result = mysql_query($query)
or die("Query failed: " . mysql_error()); //執行使用者提交的SQL語句
//表頭輸出欄位名
printf('<tr>');
$numfields = mysql_num_fields($result);
for ($i=0; $i < $numfields; $i++) // Header
{ echo '<th>'.mysql_field_name($result, $i).'</th>'; }
echo "</tr>/n";
//輸出結果
while ($row = mysql_fetch_row($result)) {
printf('<tr>');
$cnt = count($row);
for ($i=0; $i<$cnt; $i++){
if ($row[$i] != NULL){
echo('<td>'.$row[$i].'</td>');
}else{
echo('<td> </td>');
}
}
printf('</tr>');
}
mysql_free_result($result);//釋放結果
mysql_close($link);
}
?>
</table>
3、form3.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>PHP&Ajax學習</title>
<script language="javascript">
//這是《Ajax開發精要——概念、案例與架構》隨書提供的原始碼,下載地址:http://www.broadview.com.cn/Html/resource/sourcecode.rar
//檔案:sourcecode/AjaxCh05/ajax_func.js
//代碼注釋已經夠清晰,但徹底瞭解還有看原書。
var page = "";
//定義XMLHttpRequest對象執行個體
var http_request = false;
//定義可複用的http請求發送函數
function send_request(method,url,content,responseType,callback) {//初始化、指定處理函數、發送請求的函數
http_request = false;
//開始初始化XMLHttpRequest對象
if(window.XMLHttpRequest) { //Mozilla 瀏覽器
http_request = new XMLHttpRequest();
if (http_request.overrideMimeType) {//設定MiME類別
http_request.overrideMimeType("text/xml");
}
}
else if (window.ActiveXObject) { // IE瀏覽器
try {
http_request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
http_request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
if (!http_request) { // 異常,建立對象執行個體失敗
window.alert("不能建立XMLHttpRequest對象執行個體.");
return false;
}
if(responseType.toLowerCase()=="text") {
//http_request.onreadystatechange = processTextResponse;
http_request.onreadystatechange = callback;
}
else if(responseType.toLowerCase()=="xml") {
//http_request.onreadystatechange = processXMLResponse;
http_request.onreadystatechange = callback;
}
else {
window.alert("響應類別參數錯誤。");
return false;
}
// 確定發送請求的方式和URL以及是否非同步執行下段代碼
if(method.toLowerCase()=="get") {
http_request.open(method, url, true);
}
else if(method.toLowerCase()=="post") {
http_request.open(method, url, true);
http_request.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
}
else {
window.alert("http請求類別參數錯誤。");
return false;
}
http_request.send(content);
}
// 處理返迴文本格式資訊的函數
function processTextResponse() {
if (http_request.readyState == 4) { // 判斷對象狀態
if (http_request.status == 200) { // 資訊已經成功返回,開始處理資訊
res.innerHTML = http_request.responseText; //這是本人修改過的結果,將查詢資料顯示在<span id="res"></span>中
} else { //頁面不正常
alert("您所請求的頁面有異常。");
}
}
}
//處理返回的XML格式文檔的函數
function processXMLResponse() {
if (http_request.readyState == 4) { // 判斷對象狀態
if (http_request.status == 200) { // 資訊已經成功返回,開始處理資訊
document.writeln(http_request.responseXML);
alert("XML文檔響應。");
} else { //頁面不正常
alert("您所請求的頁面有異常。");
}
}
}
</script>
<script language="javascript">
//提取使用者的資料,並發送到資料庫
function query(){
var host,username,password,database,sql
host = document.form1.host.value
username = document.form1.username.value
password = document.form1.password.value
database = document.form1.database.value
sql = document.form1.sql.value
var str;
str = "host="+host+"&username="+username+"&password="+password+"&database="+database+"&sql="+sql+"&action=submitted";
send_request("POST","query.php",str,"text",processTextResponse);
}
</script>
</head>
<body>
<center>
<table width="80%" border="1" cellpadding="0" cellspacing="1" bordercolor="#000000" >
<caption align="left">
資料庫設定
</caption>
<tr>
<td><form id="form1" name="form1" method="post" action="index.php" onsubmit="this.action.value = 'submitted';return true; //提交時改變action的值">
<p align="left">主 機:
<label>
<input name="host" type="text" value="localhost" />
</label>
</p>
<p align="left">用 戶 名:
<label>
<input name="username" type="text" value="root" />
</label>
</p>
<p align="left">密 碼:
<label>
<input name="password" type="password" value="zp" />
</label>
</p>
<p align="left">數 據 庫:
<label>
<input name="database" type="text" value="sites" />
</label>
</p>
<p align="left">SQL語句:
<label>
<input name="sql" type="text" value="show tables" size="50" />
</label>
</p>
<center>
<input type="hidden" name="action" value="unsubmitted" />
<input type="button" name="Submit" value="執行" onclick="query();" /><!--執行時擷取使用者資料並通過Ajax發送到服務端 -->
<label></label>
<label></label>
</center>
</form></td>
</tr>
</table>
<span id="res"></span>
</center>
</body>
</html>