欢迎访问我的个人空间! 本人其它空间1:  http://my.tv.cctv.com/?172135 本人其它空间2:http://www.phpchina.com/?23522 欢迎访问!

AJAX在PHP中的简单使用

上一篇 / 下一篇  2008-04-01 22:49:04

AJAX无疑是2005年炒的最热的Web开发技术之一,当然,这个功劳离不开Google。我只是一个普通开发者,使用AJAX的地方不是特别多,我就简单的把我使用的心得说一下。(本文假设用户已经具有Javascrīpt、HTMLCSS等基本的Web开发能力)

PHPChina 开源社区门户@4W&PwF3G X\;X'd
[  AJAX介绍 ]

Ajax是使用客户端脚本与Web服务器交换数据的Web应用开发方法。Web页面不用打断交互流程进行重新加裁,就可以动态地更新。使用Ajax,用户可以创建接近本地桌面应用的直接、高可用、更丰富、更动态的Web用户界面。

异步Javascrīpt和XML(AJAX)不是什么新技术,而是使用几种现有技术——包括级联样式表(CSS)、Javascrīpt、XHTML、XML和可扩展样式语言转换(XSLT),开发外观及操作类似桌面软件的Web应用软件。

[  AJAX执行原理 ]

一个Ajax交互从一个称为XMLHttpRequest的Javascrīpt对象开始。如同名字所暗示的,它允许一个客户端脚本来执行HTTP请求,并且将会解析一个XML格式的服务器响应。Ajax处理过程中的第一步是创建一个XMLHttpRequest实例。使用HTTP方法(GET或POST)来处理请求,并将目标URL设置到XMLHttpRequest对象上。

当你发送HTTP请求,你不希望浏览器挂起并等待服务器的响应,取而代之的是,你希望通过页面继续响应用户的界面交互,并在服务器响应真正到达后处理它们。要完成它,你可以向XMLHttpRequest注册一个回调函数,并异步地派发XMLHttpRequest请求。控制权马上就被返回到浏览器,当服务器响应到达时,回调函数将会被调用。

[  AJAX实际应用 ]

PHPChina 开源社区门户h.?V.qp z6P
1. 初始化Ajax

Ajax实际上就是调用了XMLHttpRequest对象,那么首先我们的就必须调用这个对象,我们构建一个初始化Ajax的函数:

/**
D?WK_/O7o~;O0 * 初始化一个xmlhttp对象
D%}2C,@eLq;yD`^0 */

"F4bp!E9l%e$eE(C~j0function InitAjax()
:b@Z3G E7sb0{PHPChina 开源社区门户{XJ6r-Oby
 var ajax=false;
+O Ri5l/dS'x0]0 try {
;E m i3N] vHRwY T0  ajax = new ActiveXObject("Msxml2.XMLHTTP");
;J)tE)n(Q9w7O3Z I0 } catch (e) { PHPChina 开源社区门户Oh1f0d;b:mg2F6y1Jzap
  try {
q!y%sQ%U w0   ajax = new ActiveXObject("Microsoft.XMLHTTP"); PHPChina 开源社区门户7`Au;l n`z e
  } catch (E) { PHPChina 开源社区门户'S$W5_)yo'JU
   ajax = false; PHPChina 开源社区门户/Sr0m vR4f
  } PHPChina 开源社区门户-xM*T1M"xL}fbHE
 }PHPChina 开源社区门户|TzV3T/N:~
 if (!ajax && typeof XMLHttpRequest!='undefined') {
g-kX@0@D z8k0  ajax = new XMLHttpRequest();
)DOY \~s*WH0 } PHPChina 开源社区门户;g Ho9y P#[
 return ajax;
c^4?If w0}

你也许会说,这个代码因为要调用XMLHTTP组件,是不是只有IE浏览器能使,不是的经我试验,Firefox也是能使用的。PHPChina 开源社区门户m6a1R*HG%b
那么我们在执行任何Ajax操作之前,都必须先调用我们的InitAjax()函数来实例化一个Ajax对象。

PHPChina 开源社区门户t.sCx)P9MTuQ
2. 使用Get方式

现在我们第一步来执行一个Get请求,加入我们需要获取 /show.php?id=1的数据,那么我们应该怎么做呢?PHPChina 开源社区门户6f(n w.h`Fm ] S
假设有一个链接:<a href="/show.php?id=1">新闻1</a>,我点该链接的时候,不想任何刷新就能够看到链接的内容,那么我们该怎么做呢?

//将链接改为:
X4Uhv2B;q#_;R}&v0
<a href="#" ōnClick="getNews(1)">新闻1</a>

//并且设置一个接收新闻的层,并且设置为不显示:PHPChina 开源社区门户N E-k:H'p
<div id="show_news"></div>

同时构造相应的Javascrīpt函数:

function getNews(newsID)PHPChina 开源社区门户}l NG@v.p?/e9ANK\
{PHPChina 开源社区门户v g+ij%YX2c)i&h
 //如果没有把参数newsID传进来PHPChina 开源社区门户,K'oky8rh r4vw
 if (typeof(newsID) == 'undefined')PHPChina 开源社区门户*d#Emn8zw*wx
 {
m2]_$WH|x0  return false;
gM&^4Wdf0 }PHPChina 开源社区门户O~ WB/I
 //需要进行Ajax的URL地址PHPChina 开源社区门户N0ba]&{1tL
 var url = "/show.php?id="+ newsID;

 //获取新闻显示层的位置
l2H^6^v/P]&Q|2d8q4}0 var show = document.getElementById("show_news");

 //实例化Ajax对象PHPChina 开源社区门户 V1kJZ4Tc1c4y
 var ajax = InitAjax();

 //使用Get方式进行请求PHPChina 开源社区门户,d%Dr8\+{ X
 ajax.open("GET", url, true);

 //获取执行状态
I4L1kS5](@0 ajax.onreadystatechange = function() { PHPChina 开源社区门户/sCfkrSz
  //如果执行是状态正常,那么就把返回的内容赋值给上面指定的层PHPChina 开源社区门户7[:M&CiIF
  if (ajax.readyState == 4 && ajax.status == 200) { PHPChina 开源社区门户+y8d%C#K4m W1lu
   show.innerHTML = ajax.responseText; PHPChina 开源社区门户2}H0[8O!lX
  } PHPChina 开源社区门户 q%uJ$K;u:q:\
 }
7u+J.}+tO6H/C#n"S)Y0 //发送空PHPChina 开源社区门户`6b^y7E.p1HV
 ajax.send(null);
4A4L E Kez0}

那么当,当用户点击“新闻1”这个链接的时候,在下面对应的层将显示获取的内容,而且页面没有任何刷新。当然,我们上面省略了show.php这个文件,我们只是假设show.php文件存在,并且能够正常工作的从数据库中把id为1的新闻提取出来。

这种方式适应于页面中任何元素,包括表单等等,其实在应用中,对表单的操作是比较多的,针对表单,更多使用的是POST方式,这个下面将讲述。

PHPChina 开源社区门户"YJ\~]%FH8|x
3. 使用POST方式

其实POST方式跟Get方式是比较类似的,只是在执行Ajax的时候稍有不同,我们简单讲述一下。
@H_(Z#e$MT0假设有一个用户输入资料的表单,我们在无刷新的情况下把用户资料保存到数据库中,同时给用户一个成功的提示。

//构建一个表单,表单中不需要action、method之类的属性,全部由ajax来搞定了。PHPChina 开源社区门户!lI v4uw6v bn/} E
<form. name="user_info">
dx4[b!xE0 姓名:<input type="text" name="user_name" /><br />PHPChina 开源社区门户Q}m8[;B*y
 年龄:<input type="text" name="user_age" /><br />PHPChina 开源社区门户5x9G5P+o CD9Z7R
 性别:<input type="text" name="user_sex" /><br />

 <input type="button" value="提交表单" ōnClick="saveUserInfo()">PHPChina 开源社区门户$L} ^ q;q3kl@V+x
</form>
;KUS4@ z Gz q(e)c M/i0//构建一个接受返回信息的层:
^)qY L&Q;L$R2@:@0<div id="msg"></div>

我们看到上面的form表单里没有需要提交目标等信息,并且提交按钮的类型也只是button,那么所有操作都是靠onClick事件中的saveUserInfo()函数来执行了。我们描述一下这个函数:

function saveUserInfo()PHPChina 开源社区门户:@{z Ir0N2} UA0j
{
j.g NU^-hTD'}0 //获取接受返回信息层
4Bl$_#Mq u7a#AI0 var msg = document.getElementById("msg");

 //获取表单对象和用户信息值PHPChina 开源社区门户UkFoh1~ n
 var f = document.user_info;PHPChina 开源社区门户? B5r c6[bZqh
 var userName = f.user_name.value;PHPChina 开源社区门户A9e,_8wx8];c
 var userAge  = f.user_age.value;
\)z Pz {4w0 var userSex  = f.user_sex.value;

 //接收表单的URL地址
5S$C2I `xU0 var url = "/save_info.php";

 //需要POST的值,把每个变量都通过&来联接PHPChina 开源社区门户(n2p4d-W gm%m/Lz2Z'n
 var postStr  = "user_name="+ userName +"&user_age="+ userAge +"&user_sex="+ userSex;

 //实例化Ajax
K6y;IWq[[0 var ajax = InitAjax();

 //通过Post方式打开连接
T;P5E"qC)b0 ajax.open("POST", url, true);

 //定义传输的文件HTTP头信息
1GZ7J(Y0d8rw0 ajax.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); 

 //发送POST数据
*P{'d V h*W$e'q0 ajax.send(postStr);

 //获取执行状态
cX!` Z+_8j#ha/e0 ajax.onreadystatechange = function() { PHPChina 开源社区门户*o Z0kZ~g lc"L,c.\
  //如果执行状态成功,那么就把返回信息写到指定的层里PHPChina 开源社区门户6[V5t9Pyo.Lu
  if (ajax.readyState == 4 && ajax.status == 200) { PHPChina 开源社区门户h+I@$[uP4iUO A;ww
   msg.innerHTML = ajax.responseText; PHPChina 开源社区门户un {6@J gq9h
  } PHPChina 开源社区门户n T6a$F4c7P;R:nN;M
 }
lv*k!tz0}

大致使用POST方式的过程就是这样,当然,实际开发情况可能会更复杂,这就需要开发者去慢慢琢磨。

4. 异步回调(伪Ajax方式)

一般情况下,使用Get、Post方式的Ajax我们都能够解决目前问题,只是应用复杂程度,当然,在开发中我们也许会碰到无法使用Ajax的时候,但是我们又需要模拟Ajax的效果,那么就可以使用伪Ajax的方式来实现我们的需求。

伪Ajax大致原理就是说我们还是普通的表单提交,或者别的什么的,但是我们却是把提交的值目标是一个浮动框架,这样页面就不刷新了,但是呢,我们又需要看到我们的执行结果,当然可以使用Javascrīpt来模拟提示信息,但是,这不是真实的,所以我们就需要我们的执行结果来异步回调,告诉我们执行结果是怎么样的。

假设我们的需求是需要上传一张图片,并且,需要知道图片上传后的状态,比如,是否上传成功、文件格式是否正确、文件大小是否正确等等。那么我们就需要我们的目标窗口把执行结果返回来给我们的窗口,这样就能够顺利的模拟一次Ajax调用的过程。

以下代码稍微多一点, 并且涉及Smarty模板技术,如果不太了解,请阅读相关技术资料。

上传文件upload.html

//上传表单,指定target属性为浮动框架iframe1
1M&is^9w0uL&I0<form. action="/upload.php" method="post"  enctype="multipart/form-data" name="upload_img" target="iframe1">PHPChina 开源社区门户8G m*f2@ `-xd.g$J
 选择要上传的图片:<input type="file" name="image"><br />PHPChina 开源社区门户1I!H~Hu,x
 <input type="submit" value="上传图片">PHPChina 开源社区门户 m4i T2cc jW?~
</form>PHPChina 开源社区门户 D?+^Z;b!ctJ8F
//显示提示信息的层PHPChina 开源社区门户`sR:z!^e7Z^`
<div id="message" style="display:none"></div>

//用来做目标窗口的浮动框架
[ l*jfX9g0<iframe. name="iframe1" width="0" height="0" scrolling="no"></iframe>

PHPChina 开源社区门户9qJ/E|6s3S3M3f_
处理上传的PHP文件upload.php

<?php

/* 定义常量 */

//定义允许上传的MIME格式PHPChina 开源社区门户X+J7h RlV"L P c
define("UPLOAD_IMAGE_MIME", "image/pjpeg,image/jpg,image/jpeg,image/gif,image/x-png,image/png");
(rv Enja.N f1zK~0//图片允许大小,字节PHPChina 开源社区门户 oh4`v4J6dWj s"p-N
define("UPLOAD_IMAGE_SIZE", 102400);PHPChina 开源社区门户 T I}7Y4~v
//图片大小用KB为单位来表示PHPChina 开源社区门户6ElK2mM"dB/r9FQ
define("UPLOAD_IMAGE_SIZE_KB", 100); PHPChina 开源社区门户Zpq v3B Q;md?%\)Y
//图片上传的路径PHPChina 开源社区门户k#cn2o$~9O,L@ ^
define("UPLOAD_IMAGE_PATH", "./upload/");

//获取允许的图像格式PHPChina 开源社区门户-}TvH|-O L
$mime = explode(",", USER_FACE_MIME);PHPChina 开源社区门户y+xcav[
$is_vaild = 0;

//遍历所有允许格式PHPChina 开源社区门户 u,UNmvX(Rm_
foreach ($mime as $type)
DIKw/~fD3zJ`!C$J0{PHPChina 开源社区门户\E,f]K
 if ($_FILES['image']['type'] == $type)PHPChina 开源社区门户*~wZ8N.M;uD1O+Dj
 {PHPChina 开源社区门户&s!}&re-gzL5h AQ!n
  $is_vaild = 1;
ca0x.j%L C0 }PHPChina 开源社区门户3Xu2{;h~^X
}

//如果格式正确,并且没有超过大小就上传上去PHPChina 开源社区门户!j&^6qP#p-n9g6^
if ($is_vaild && $_FILES['image']['size']<=USER_FACE_SIZE && $_FILES['image']['size']>0)PHPChina 开源社区门户v(H*FS5W
{PHPChina 开源社区门户 f/~9F uK7[
 if (move_uploaded_file($_FILES['image']['tmp_name'], USER_IMAGE_PATH . $_FILES['image']['name'])) PHPChina 开源社区门户r u/\F7lrA
 {
7[1b:s8~YrC [k0  $upload_msg ="上传图片成功!";PHPChina 开源社区门户M|`pj
 }
l:c(p;^uF[|0 else PHPChina 开源社区门户w%M J'k4[)YA O uX
 {PHPChina 开源社区门户C3H6e)\;h
  $upload_msg = "上传图片文件失败";PHPChina 开源社区门户{M$Id `n
 }
2y7F)X XU(|0}PHPChina 开源社区门户g%hD~Q(A,| E
else
5VH4p*P!XMyz W&]0{
g FZ#ZG'`R$n0 $upload_msg = "上传图片失败,可能是文件超过". USER_FACE_SIZE_KB ."KB、或者图片文件为空、或文件格式不正确";
'Y3S"^2p#B#W8M0}

//解析模板文件PHPChina 开源社区门户)U1z W)B f7`
$smarty->assign("upload_msg", $upload_msg);PHPChina 开源社区门户2BP9e pX$lB$P}
$smarty->display("upload.tpl");

?>

模板文件:upload.tpl

{if $upload_msg != ""}
0AtRf6iG&FFa@Z0 callbackMessage("{$upload_msg}"); 
*uk$c:I[]%b!Znm0{/if}

//回调的Javascrīpt函数,用来在父窗口显示信息PHPChina 开源社区门户8I1cg"utp
function callbackMessage(msg)PHPChina 开源社区门户 jMc\u/|wd
{
Yyl8C3`\iIAh:x0 //把父窗口显示消息的层打开PHPChina 开源社区门户;mc-vo!?axV H:}
 parent.document.getElementById("message").style.display = "block";
6e7N b&\?3`}B `p0 //把本窗口获取的消息写上去PHPChina 开源社区门户:Za`+K"S,X,xE
 parent.document.getElementById("message").innerHTML = msg;
_*qrTfX0 //并且设置为3秒后自动关闭父窗口的消息显示PHPChina 开源社区门户/T6f2S5RkdSX
 setTimeout("parent.document.getElementById('message').style.display = 'none'", 3000);PHPChina 开源社区门户4t0eix2K\!ZuK
}

PHPChina 开源社区门户-]$W(\$[4CV
使用异步回调的方式过程有点复杂,但是基本实现了Ajax、以及信息提示的功能,如果接受模板的信息提示比较多,那么还可以通过设置层的方式来处理,这个随机应变吧。

[  结束语 ]

这是一种非常良好的Web开发技术,虽然出现时间比较长,但是到现在才慢慢火起来,也希望带给Web开发界一次变革,让我们朝RIA(富客户端)的开发迈进,当然,任何东西有利也有弊端,如果过多的使用Javascrīpt,那么客户端将非常臃肿,不利于用户的浏览体验,如何在做到快速的亲前提下,还能够做到好的用户体验,这就需要Web开发者共同努力了。


TAG: Ajax AJAX ajax

 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

Open Toolbar