一、我所理解的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" οnsubmit="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="执行" οnclick="query();" /><!--执行时获取用户数据并通过Ajax发送到服务端 -->
<label></label>
<label></label>
</center>
</form></td>
</tr>
</table>
<span id="res"></span>
</center>
</body>
</html>