乌秋博客
梦想在左,生活在右。   

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


[ AJAX介绍 ]

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

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


[ AJAX执行原理 ]

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

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


[ AJAX实际应用 ]


1. 初始化Ajax

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

/**
* 初始化一个xmlhttp对象
*/
function InitAjax()
{
 var ajax=false; 
 try { 
  ajax = new ActiveXObject("Msxml2.XMLHTTP"); 
 } catch (e) { 
  try { 
   ajax = new ActiveXObject("Microsoft.XMLHTTP"); 
  } catch (E) { 
   ajax = false; 
  } 
 }
 if (!ajax && typeof XMLHttpRequest!='undefined') { 
  ajax = new XMLHttpRequest(); 
 } 
 return ajax;
}

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


2. 使用Get方式

现在我们第一步来执行一个Get请求,加入我们需要获取 /show.php?id=1的数据,那么我们应该怎么做呢?
假设有一个链接:
<a href="/show.php?id=1">新闻1</a>
,我点该链接的时候,不想任何刷新就能够看到链接的内容,那么我们该怎么做呢?

//将链接改为:
<a href="#" onClick="getNews(1)">新闻1</a>


//并且设置一个接收新闻的层,并且设置为不显示:
<div id="show_news"></div>


同时构造相应的JavaScript函数:

function getNews(newsID)
{
 //如果没有把参数newsID传进来
 if (typeof(newsID) == 'undefined')
 {
  return false;
 }
 //需要进行Ajax的URL地址
 var url = "/show.php?id="+ newsID;

 //获取新闻显示层的位置
 var show = document.getElementById("show_news"); 

 //实例化Ajax对象
 var ajax = InitAjax();

 //使用Get方式进行请求
 ajax.open("GET", url, true); 

 //获取执行状态
 ajax.onreadystatechange = function() { 
  //如果执行是状态正常,那么就把返回的内容赋值给上面指定的层
  if (ajax.readyState == 4 && ajax.status == 200) { 
   show.innerHTML = ajax.responseText; 
  } 
 }
 //发送空
 ajax.send(null); 
}

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

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


3. 使用POST方式

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

//构建一个表单,表单中不需要action、method之类的属性,全部由ajax来搞定了。
<form name="user_info">
 姓名:<input type="text" name="user_name" />
 年龄:<input type="text" name="user_age" />
 性别:<input type="text" name="user_sex" />

 <input type="button" value="提交表单" onClick="saveUserInfo()">
</form>
//构建一个接受返回信息的层:
<div id="msg"></div>

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

function saveUserInfo()
{
 //获取接受返回信息层
 var msg = document.getElementById("msg");

 //获取表单对象和用户信息值
 var f = document.user_info;
 var userName = f.user_name.value;
 var userAge  = f.user_age.value;
 var userSex  = f.user_sex.value;

 //接收表单的URL地址
 var url = "/save_info.php";

 //需要POST的值,把每个变量都通过&来联接
 var postStr  = "user_name="+ userName +"&user_age="+ userAge +"&user_sex="+ userSex;

 //实例化Ajax
 var ajax = InitAjax();

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

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

 //发送POST数据
 ajax.send(postStr);

 //获取执行状态
 ajax.onreadystatechange = function() { 
  //如果执行状态成功,那么就把返回信息写到指定的层里
  if (ajax.readyState == 4 && ajax.status == 200) { 
   msg.innerHTML = ajax.responseText; 
  } 
 } 
}

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


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

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

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

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

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

上传文件:upload.html

//上传表单,指定target属性为浮动框架iframe1
<form action="/upload.php" method="post"  enctype="multipart/form-data" name="upload_img" target="iframe1">
 选择要上传的图片:<input type="file" name="image">
 <input type="submit" value="上传图片">
</form>
//显示提示信息的层
<div id="message" style="display:none"></div>

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


处理上传的PHP文件:upload.php

<?php

/* 定义常量 */

//定义允许上传的MIME格式
define("UPLOAD_IMAGE_MIME", "image/pjpeg,image/jpg,image/jpeg,image/gif,image/x-png,image/png"); 
//图片允许大小,字节
define("UPLOAD_IMAGE_SIZE", 102400);
//图片大小用KB为单位来表示
define("UPLOAD_IMAGE_SIZE_KB", 100); 
//图片上传的路径
define("UPLOAD_IMAGE_PATH", "./upload/"); 

//获取允许的图像格式
$mime = explode(",", USER_FACE_MIME);
$is_vaild = 0;

//遍历所有允许格式
foreach ($mime as $type)
{
 if ($_FILES['image']['type'] == $type)
 {
  $is_vaild = 1;
 }
}

//如果格式正确,并且没有超过大小就上传上去
if ($is_vaild && $_FILES['image']['size']<=USER_FACE_SIZE && $_FILES['image']['size']>0)
{
 if (move_uploaded_file($_FILES['image']['tmp_name'], USER_IMAGE_PATH . $_FILES['image']['name'])) 
 {
  $upload_msg ="上传图片成功!";
 } 
 else 
 {
  $upload_msg = "上传图片文件失败";
 }
}
else
{
 $upload_msg = "上传图片失败,可能是文件超过". USER_FACE_SIZE_KB ."KB、或者图片文件为空、或文件格式不正确";
}

//解析模板文件
$smarty->assign("upload_msg", $upload_msg);
$smarty->display("upload.tpl");

?>

模板文件:upload.tpl

{if $upload_msg != ""}
 callbackMessage("{$upload_msg}"); 
{/if}

//回调的JavaScript函数,用来在父窗口显示信息
function callbackMessage(msg)
{
 //把父窗口显示消息的层打开
 parent.document.getElementById("message").style.display = "block";
 //把本窗口获取的消息写上去
 parent.document.getElementById("message").innerHTML = msg;
 //并且设置为3秒后自动关闭父窗口的消息显示
 setTimeout("parent.document.getElementById('message').style.display = 'none'", 3000);
}


使用异步回调的方式过程有点复杂,但是基本实现了Ajax、以及信息提示的功能,如果接受模板的信息提示比较多,那么还可以通过设置层的方式来处理,这个随机应变吧。


[ 结束语 ]

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


(说明:以上代码不能直接运行,只是一个演示的作用,如果代码或者文章不正确的地方,敬请指正)

(附:需要获取更多关于AJAX的资料,请参考连接:http://www.51cto.com/html/2005/1121/11736.htm
posted at 06/01/01 00:17 | 技术文摘 - PHP | 浏览(22) | 引用(1) | 评论

在AJAX开发中集成数据库技术
  一、引言

  如今,有相当多的Web应用程序,如Backpack,Blinksale和Gmail,都把数据库技术与AJAX集成到一起。通过提供与数据库通讯而不用刷新浏览器这种强有力的技术,这种集成对web应用程序和用户体验产生巨大的影响-这意味着,在用户继续其它交互的同时可以实现实时的数据传输。

  本文将集中讨论上述技术集成机理。同时提供了完整的参考源码。这个示例是一个简单的职务记录应用程序,其中每个职务包含一个标题,描述和日期-允许用户添加、编辑和删除职务。所有这些都是你与数据库记录数据打交道时的基本操作,但是这个应用程序更进了一步。一个职务可以变化成一个可编辑的表单-它将被从数据库中加以保存或删除,以及以其新状态显示而不需要刷新浏览器并中断用户操作。

  在本文中,我假定你已经初步了解AJAX、MySQL和PHP,或一类似的服务器端语言。如果你还没有创建过XML HTTP Request对象,那么可以先参考我的文章“怎样使用AJAX”。下面,首先让我们讨论数据库的问题。

  二、创建数据库

  你需要做的第一件事是创建数据库表来为这些职务存储数据。我创建了一个叫informit_ajax的MySQL表-它拥有ID,title,description和date字段-这些都是在本文中不断重复出现的变量。下面是创建该表的代码:
CREATE TABLE ′informit_ajax′ (
′id′ int(11) NOT NULL auto_increment,
′date′ datetime NOT NULL default '0000-00-00 00:00:00',
′description′ longtext NOT NULL,
′title′ varchar(100) NOT NULL default '',
PRIMARY KEY (′id′)
) TYPE=MyISAM;

  你可以用任何MySQL查询工具或开发应用程序所用的语言来执行这段代码。一旦准备好数据库,接下来就需要创建向PHP后台发出请求的前端文件。

  三、发出请求

  这里的索引HTML文件是一简单的数据占位符-它将被从数据库中加以分析。该文件包含到JavaScript和CSS文件的参考;还包含一个发出首次请求的onload处理器和三个div标签:

  · Layout-用于把页面内容居中

  · loading-在被请求的数据加载期间加载消息,它将为HTTPRequest对象所接收

  · posts-用于显示每一个分析后的职务数据
<head>
<title>How to Integrate a Database with AJAX</title>
<link href="css/layout.css" rel="stylesheet" type="text/css" />
<script src="js/request.js"></script>
<script src="js/post.js"></script>
</head> 
<body onload="javascript:makeRequest('services/post.php?method=get');">
<div id="layout" align="center">
<div id="posts"></div>
<p><input type="button" value="add a post" onmousedown="javascript:makeRequest('services/post.php?method=save');" /></p>
<p><div id="loading"></div></p>
</div>

</body>

  当页面装载时产生第一个请求。这个请求发送一个get查询到一个我们稍后会创建的PHP类;但是首先我们需要为请求的响应创建分析方法。JavaScript请求文件负责处理所有的基础工作,例如创建对象,发送请求以及检查准备状态等。当从Request对象收到响应时,我用这个JavaScript职务文件来处理这些职务的HTML生成。onResponse方法是相当强壮的,因为它以文本和表单两种版本处理每个职务的HTML页面生成,并且把它们放置到它们自己定制的div标签中;这样以来,我们就可以容易地在用户交互期间定位它们。通过这种方法,我们可以在每个职务的文本和表单版本之间进行切换-这可以通过点击一个"edit this post"链接来实现。下面是针对每个职务创建的HTML页面的代码,你可以在本文相应的下载源文件中看到完整的方法实现。
var html = "<div class='post' id='post_"+ i +"' "+ postDisplay +">"
+ "<div class='title' id='title_"+ i +"'>"+ _title +"</div>"
+ "<div class='description' id='description_"+ i +"'>"+ _description +"</div>"
+ "<div class='date' id='date_"+ i +"'>"+ _date +"</div>"
+ "<a href=\"javascript:toggle('"+ i +"');\">edit this post</a><br/>"
+ "</div>"
+ "<div class='post' id='formPost_"+ i +"' "+ formPostDisplay +">"
+ "<div class='title'><input type='text' name='title' id='formTitle_"+ i +"' size='60' value='"+ _title +"'></div>"
+ "<div class='description'><textarea type='text' id='formDescription_"+ i +"' wrap='virtual' cols='60' rows='15'>"+ _description +"</textarea></div>"
+ "<div class='date'>"+ _date +"</div>"
+ "<input type='button' name='cancel' value='cancel' onclick=\"javascript:toggle('"+ i +"');\">"
+ "<input type='button' name='delete' value='delete this post' onclick=\"javascript:deletePost("+ _id +");\">"
+ "<input type='button' name='submit' value='save this post' onclick=\"javascript:saveNewPost("+ _id +","+ i +");\">"
+ "</div>"
+ "<p>"nbsp;</p>";

  每个职务的文本版本简单地显示标题,描述和日期以及一个"edit this post"链接。每个职务的表单版本有三个按钮:

  ·"cancel"按钮-简单地把职务的状态切换回文本版本。

  ·"delete this post"按钮-把当前职务的ID发送给PHP对象以从数据库中把它删除。

  ·"save this post"按钮-允许用户把新的或编辑过的职务保存到服务器。

  处理服务器端请求通讯的核心方法有onResponse,saveNewPost,deletePost和getPost方法;还有存储当前正操作的职务索引的一个getter和一个setter方法。这些getter/setter方法把当前索引值提供给这些核心方法,这样正确的职务就可以用基于该索引的正确信息进行更新。下面是针对每个核心方法(不包括onResponse,因为我们以前观察过它的功能)的简短描述和代码示例:

  · 下面的saveNewPost方法通过收集并把表单输入值发送给PHP对象来保存新的职务并且把getPost方法设置为onreadystatechange的回叫方法:
function saveNewPost(_id, _index){
 var newDescription = document.getElementById("formDescription_"+ _index).value;
 var newTitle = document.getElementById("formTitle_"+ _index).value;
 setIndex(_index);
 sendRequest("services/post.php?method=save"id="+ _id +""title="+ newTitle +""description="+ newDescription, getPost);
}

  · 下面的getPost方法是一个回调方法-它负责当从PHP对象收到响应时更新单独的职务:
function getPost(){
 if(checkReadyState(request)) {
  var response = request.responseXML.documentElement;
  var _title = response.getElementsByTagName('title')[getIndex()].firstChild.data;
  var _description = response.getElementsByTagName('description')[getIndex()].firstChild.data;
  var _date = response.getElementsByTagName('date')[getIndex()].firstChild.data;

  document.getElementById("title_"+ getIndex()).innerHTML = _title;
  document.getElementById("description_"+ getIndex()).innerHTML = _description;
  document.getElementById("date_"+ getIndex()).innerHTML = _date;
  toggle(getIndex());
 }
}

  · 下面的deletePost方法把当前索引作为一个请求发送给PHP对象,这最终将删除数据库中的记录并以更新的职务进行响应:
function deletePost(_id){
 sendRequest("services/post.php?method=delete"id="+ _id, onResponse);
}

  令人惊讶的是,最复杂的部分已经结束了。下面让我们分析最为关键的部分-数据库交互。
  四、与数据库交互

  为了实现与数据库的交互,你需要创建方法用于检索,插入,代替和删除职务。我选择创建一个post类,其中有get,save和delete方法来处理这些交互。这个类还有一个到数据库连接文件(用于连接到数据库)的参考。你必须用自己的数据库信息来代替登录,口令和数据库名。

DEFINE ('DB_USER', 'USERNAME');
DEFINE ('DB_PASSWORD', 'PASSWORD');
DEFINE ('DB_HOST', 'localhost');
DEFINE ('DB_NAME', 'DATABASE');
$dbc = @mysql_connect (DB_HOST, DB_USER, DB_PASSWORD) OR die ('Could not connect to MySQL: ' . mysql_error() ); 


  到连接文件的参考以及数据库的名字位于该类的构造器中。你的构造器看上去应该与下面代码相似:

function Post(){
 require_once('mysql_connect.php');
 $this->table = "informit_ajax";
} 


  下面的dbConnect方法负责创建连接-通过把登录信息传送给数据库;这个方法被重用于查询数据库前的所有核心方法中:

function dbConnect(){
 DEFINE ('LINK', mysql_connect (DB_HOST, DB_USER, DB_PASSWORD));
} 


  下面的get方法循环遍历数据库表,它基于数据库行创建一个XML字符串,并把该字符串返回给请求者:

function get(){
 $this->dbConnect();
 $query = "SELECT * FROM $this->table ORDER BY id";
 $result = mysql_db_query (DB_NAME, $query, LINK);
 $xml = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n";
 $xml .= "<posts>\n";
 while($row = mysql_fetch_array($result)) {
  $xml .= "<post>\n";
  $xml .= "<id>" . $row['id'] . "</id>\n";
  $xml .= "<date>" . $row['date'] . "</date>\n";
  $xml .= "<title><![CDATA[" . $row['title'] . "]]></title>\n";
  $xml .= "<description><![CDATA[" . $row['description'] . "]]></description>\n";
  $xml .= "</post>\n";
 }
 $xml .= "</posts>";
 mysql_close();
 header("Content-Type: application/xml; charset=UTF-8");
 echo $xml;
} 


  下面的save方法通过处理更新和插入位置实现两个目的:

function save($id, $title, $description){
$this->dbConnect();
$query = "SELECT * FROM $this->table WHERE id='$id'";
$result = @mysql_query ($query);
if (mysql_num_rows($result) > 0)
{
 $query = "UPDATE $this->table SET title='$title', description='$description', date=NOW() WHERE id='$id'";
 $result = @mysql_query($query);
}
else
{
 $query = "INSERT INTO $this->table (title, description, date) VALUES ('$title', '$description', NOW())";
 $result = @mysql_query($query);
}
mysql_close();
$this->get();
} 


  下面的delete方法负责删除一个基于被作为参数传递的ID的位置。然后调用get方法来把新的数据返回到请求文件:

function delete($id){
 $this->dbConnect();
 $query = "DELETE FROM $this->table WHERE id='$id'";
 $result = @mysql_query($query);
 mysql_close();
 $this->get();
} 


  五、综合应用

  为了把以上各部分整合到一起,需要创建一个简单的文件来承担XML HTTP请求和PHP对象之间的通讯桥梁。这时的页面不仅创建PHP对象,还接收查询并把变量传递给动态生成的方法-在此是指get,save或delete。下面的一个示例查询包括了一个$method和可靠的$id,$title和$description变量。

require_once("../classes/Post.class.php");
$post = new Post();
$post->$method($id, $title, $description); 


  以后我们还会更进一步讨论这些技术。如今的web开发看起来再次变得年轻而充满活力,而我们也很幸运地成为这种新技术时代的一部分。
posted at 05/12/26 10:40 | 技术文摘 - PHP | 浏览(13) | 引用 | 评论

PHP程序加速探索之脚本执行速度测试
  前面有提到,只有找到影响速度的代码,我们才有可能进行优化。PEAR的benchmark包中的Benchmark_Timer类和Benchmark_Iterate类,可以用来很方便地测试脚本执行的速度。(关于PEAR的安装与配置请自行查看相关资料) 。

  首先用Benchmark_Iterate类来测试程序中某个函数或类的某个方法的执行时间。

  benchmark1.php
<?
require_once('Benchmark/Iterate.php'); 
$benchmark = new Benchmark_Iterate(); 

$benchmark->run(10, 'myFunction','test'); 
$result = $benchmark->get(); 
echo "

"; print_r($result); echo "
"; 
exit; 

function myFunction($var) { 
// do something 
echo 'Hello '; 
} 
?>

  建立benchmark Iterate对象$benchmark,这个对象用来执行myFunction函数10次。

  $argument变量每次都传递给myFunction. 多次运行的分析结果存入$result,然后用benchmark对象的get()方法来获取。这个结果用print_r()输出到屏幕。通常会输出这样的结果:

Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello
Array
(
[1] => 0.000427 [2] => 0.000079 [3] => 0.000072 [4] => 0.000071 [5] => 0.000076 [6] => 0.000070 [7] => 0.000073 [8] => 0.000070 [9] => 0.000074 [10] => 0.000072 [mean] => 0.000108 [iterations] => 10)

  myFunction的每次执行,benchmark对象都会跟踪执行时间。并且会计算平均的执行时间([mean]那一行)。通过多次运行目标函数,你可以得到该函数的平均运行时间。

  在实际测试中,函数的次数应当至少1000次左右,这样可以得到较客观的结果。
posted at 05/12/19 18:59 | 技术文摘 - PHP | 浏览(19) | 引用(1) | 评论

2005年度Java十大新技术和新产品
  2005年Java世界诞生了众多的新技术和新产品,小编从中挑选了最优秀的10种新技术和新产品,这10种产品的选择标准只有唯一的一个:对未来Java的发展和应用具有重要影响。如果你有不同意见,请给我写信。

  一、JavaEE 5

  JavaEE 5不简单的由J2EE改名而来,Sun对其作了重大修改,应该算一种新技术。从提交公开审查的规范草案Java EE 5的来看,Java EE 5的关注重点是简化应用开发,尤其是大量采用元数据标注(annotation)和POJO(普通Java对象)驱动的开发方式,对平台进行了重新定义。对比此前的J2EE 1.4规范,Java EE 5最重要的新增特性包括Java持久化API(即EJB 3 entity bean)、JSF、JSTL等。

  影响指数:★★★★★

  二、Java模块系统规范(JSR-277)

  JSR-277是由Sun公司发起的一个技术规范,其目标是解决Java应用在部署时遇到的很多麻烦,例如JAR的版本问题、JAR之间的依赖问题等。按照JSR-277的规定,发布模块中将包含描述该模块信息的元数据,例如版本信息、模块中包含的资源、与其他模块的依赖关系等。规范专家组希望依靠这些统一的模块元数据来解决Java应用部署的难题。

  影响指数:★★★★★

  三、AspectJ5

  AspectJ5是AspectJ与AspectWerkz合并后推出的第一款产品,继承了二者的优点,成为目前最有影响也最为强大的AOP平台,给广大开发人员提供一个统一的AOP平台,其它进一步融合Spring,进而统一AOP开发平台。

  影响指数:★★★★

  四、BEA WebLogic Server 9.0

  被评论界称为迄今为止发布的最卓越的BEA应用服务器,为企业开发和部署SOA提供最佳开发平台――帮助企业应用SOA,并快速实现开发和部署各种任务。BEA WebLogic Server 9.0由可支持多种编程模式的企业级内核组成,能帮助IT管理人员和开发人员提高效率,降低IT项目成本,减少宕机时间,有助于用户集中精力迁移到面向服务的基础架构(SOA)上。

  影响指数:★★★★

  五、AquaLogic

  AquaLogic(此前代号为Quicksilver)是BEA新推出的企业服务总线(ESB)产品,包括六条产品线,已经正式发布有三条,分别是BEA AquaLogic消息产品线、BEA AquaLogic数据产品线、和BEA AquaLogic安全产品线。是第一个完整提供SOA解决方案的服务基础设施产品,能够以服务的形式整合来自任何平台的应用和流程。

  影响指数:★★★★

  六、SDO 2.0规范

  SDO规范是由BEA与IBM共同起草的,其目标是简化并统一应用程序处理数据的方式,该规范在JCP中的编号是JSR-235。按照BEA发布的题为“使用服务数据对象的下一代数据编程”白皮书的描述,使用SDO时,程序员可以用统一的方式访问不同的数据源,包括关系型数据库、XML数据源、web service、以及各种企业信息系统。

  影响指数:★★★

  七、开源数据库Derby

  Apache Derby是基于Java的一种数据库,是IBM公司去年向基金会开放的软件。Apache基金会推出了第一款开源Derby数据库产品。Apache Derby 10.1.1.0推出了一种开源网络驱动器,并支持用于便携产品的Java 2 Micro版本。

  影响指数:★★★

  八、Harmony

  Harmony项目是在今年5月份成立的旨在开发一个开放源代码版的基于Java平台的标准版(Java SE),这一软件是在台式机上运行Java软件所需要的。Java社群一直需要这样的开源的J2SE实现,并且有一些这方面的解决方案(例如Kaffe、Classpath等)。

  影响指数:★★★

  九、Spring框架1.2

  在这个新版本中最主要的新特性是增加了对几种持久化技术的支持,包括支持TopLink 9.0.4和10.1.3、JDO 2.0、Hibernate 3.0.3等。此外,Spring 1.2还简化了bean声明的XML格式,并且支持JDK 1.5事务标注(annotation)和JMX。

  影响指数:★★

  十、SOA门户网站

  由IBM出资建立的SOA门户网站,目前该网站包括第一批基于IBM技术的SOA最佳实践和部署模式、客户实例,以及来自IBM公司内外的分析评论。

  影响指数:★★
posted at 05/12/18 18:21 | 技术文摘 - PHP | 浏览(9) | 引用(55) | 评论

簡單購物車
這篇教學會教你如何寫一個簡單的購物車。
這個購物車會從普通的文字檔讀取商品,完全不用資料庫。
使用者可以新增,移除商品,清除或更新購物車的商品價格。
程式是使用 session 來記錄資料,不是用 cookie。

當然這個購物車不可能用來當商業用途,它的功能只有加減和計算商品價格。
這篇教學的主旨是讓你了解如何讀取文字檔裡的資料,如何使用 session 等等。

這篇教學是:

    * 普通文字檔的購物車
    * 了解如何使用 session
    * 了解如何讀取文字檔

這篇教學不是:

    * 教你如何寫商業用途的購物車
    * 教你 PHP 語法
    * 教你如何使用資料庫


首先建立一個商品目錄檔,儲存商品資料。
程式碼:
101:AA batteries (pack of 2):2.99
102:AA batteries (pack of 4):5.49
103:Backpack (black):69.99
104:Money belt with 6 compartments (black):13.49
105:Haversack (red):199.99
106:Swiss Army knife (6 blades including can opener and scissors):24.99
107:Duffel bag (steel gray):28.50
然後儲存為 catalog.txt。
資料是以 : 來區分商品號碼,商品簡介,最後價格。

接下來主程式,建立一個叫 shop.php 的檔案:
程式碼:
<?php
session_start();
if (!isset($_SESSION['cart']))
{
    $_SESSION['cart'] = array();
}
?>
上面的程式會建立一個 session,檢查是否已經有 session 的資料。
然後將一個空白陣列放入 $_SESSION['cart'] 裡。

再來是讀取目錄檔:
程式碼:
<?php
$catalogFile = "catalog.txt";
if (file_exists($catalogFile))
{
    $data = file($catalogFile);
    foreach ($data as $line)
    {
        $lineArray = explode(':', $line);
        $sku = trim($lineArray[0]);
        $catalog[$sku]['desc'] = trim($lineArray[1]);
        $catalog[$sku]['price'] = trim($lineArray[2]);
    }
}
else
{
    die("Could not find catalog file");
}
?>
首先建立一個目錄檔案的變數,儲存檔案位址。
檢查檔案是否存在,不存在停止程式。
再來用 file() 把檔案打開,然後 foreach 跑每行資料。
用 explode() 來將資料放入 $lineArray 陣列,以 : 區分。
再來用 trim() 來找陣列的第一個值,也就是商品編號。
最後建立 $catalog 的多維陣列,放入簡介和價格。

再來是增加,更新,和清除購物車:
程式碼:
<?php
if ($_POST['add'])
{
    foreach ($_POST['a_qty'] as $key => $value)
    {
        if ($value > 0)
        {
            $_SESSION['cart'][$key] = $_SESSION['cart'][$key] + $value;
        }
    }
}
else if ($_POST['update'])
{
    foreach ($_POST['u_qty'] as $key => value)
    {
        if ($value != " " && $value >= 0)
        {
            $_SESSION['cart'][$key] = $value;
        }
    }  
}
else if ($_POST['clear'])
{
    $_SESSION = array();
    session_destroy();
}
?>
第一個 if 是新增商品的動作。
它會用 foreach 跑完每個商品,如果商品的數量多於零表示要增加。
$_POST['a_qty'] 是一個包含商品數量的陣列。
如果某個商品的數量是多於零,增加到 $_SESSION['cart'] 裡面。
$key 是用來分辨商品的編號。

接下來是更新商品。
一樣如果數量不等於零或空白,更新商品數量。

然後是清除購物車。第一先建立一個空白的 $_SESSION 陣列。
記得必須先建立一個空白的 $_SESSION,然後用 session_destroy() 來清除資料。

接下來是顯示目錄裡面的商品資料:
程式碼:
<h2>Catalog</h2>
Please add items from the list below to your shopping cart.
<form action="<?php $_SERVER['PHP_SELF'] ?>" method="POST">
<table border="0" cellspacing="10">
<?php
foreach ($catalog as $key => $value)
{
    echo '<tr><td colspan=2>';
    echo '<b>', $value['desc'], '</b>';
    echo '</td></tr>';
    echo '<tr><td>';
    echo 'Price per unit: ', $catalog[$key]['price'];
    echo '</td><td>Quantity: ';
    echo '<input size="4" type="text" name="a_qty[', $key, ']">';
    echo '</td></tr>';
}
?>
<tr>
<td colspan="2">
<input type="submit" name="add" value="Add items to cart">
</td>
</tr>
</table>
上面使用了很簡單的 html 表格,應該不用解釋了。
記住 $catalog 是一個多維陣列,包含了編號,簡介和價格。
然後用 foreach 輸出每個陣列裡面的值。

最後顯示購物車:
程式碼:
<h2>Shopping cart</h2>
<table width="100%" border="0" cellspacing="10">
<?php
$total = 0;
if (is_array($_SESSION['cart']))
{
    foreach ($_SESSION['cart'] as $key => $value)
    {
        if ($value > 0)
        {
            $subtotal = $value * $catalog[$key]['price'];
            $total += $subtotal;
            echo '<tr><td>';
            echo '<b>', $value, ' unit(s) of ', $catalog[$key]['desc'], '</b>';
            echo '</td><td>';
            echo 'New quantity: <input size="4" type="text" name="u_qty[', $key, ']">';
            echo '</td></tr>';
            echo '<tr><td>';
            echo 'Price per unit: ', $catalog[$key]['price'];
            echo '</td><td>';
            echo 'Sub-total: ', sprintf("%0.2f", $subtotal);
            echo '</td></tr>';
        }
    }
}
?>
<tr>
<td><b>Total</b></td>
<td><b><?php echo sprintf("%0.2f", $total) ?></b></td>
</tr>

<tr>
<td><input type="submit" name="update" value="Update cart"></td>
<td><input type="submit" name="clear" value="Clear cart"></td>
</tr>
</table>
</form>
上面的 if 是用來測試 $_SESSION 有沒有東西,有的話表示購物車裡面有商品。
一樣用 foreach 來輸出 $_SESSION 裡面的值,然後計算它的總價。
價格包括了 subtotal (單商品的總價),還有全部商品的總價。
sprintf() 是用來格式價格的小數點。

最後將上面說的全部放在一起 (檔案 shop.php):
程式碼:
<?php
// start session
session_start();

// initialize session shopping cart
if (!isset($_SESSION['cart']))
{
    $_SESSION['cart'] = array();
}

// look for catalog file
$catalogFile = "catalog.txt";
// file is available, extract data from it
// place into $catalog array, with SKU as key
if (file_exists($catalogFile))
{
    $data = file($catalogFile);
    foreach ($data as $line)
    {
        $lineArray = explode(':', $line);
        $sku = trim($lineArray[0]);
        $catalog[$sku]['desc'] = trim($lineArray[1]);
        $catalog[$sku]['price'] = trim($lineArray[2]);
    }
}
// file is not available
// stop immediately with error
else
{
    die("Could not find catalog file");
}

// check to see if the form has been submitted
// and which submit button was clicked
// if this is an add operation
// add to already existing quantities in shopping cart
if ($_POST['add'])
{
    foreach ($_POST['a_qty'] as $key => $value)
    {
        // if the value is 0 or negative
        // don't bother changing the cart
        if ($value > 0)
        {
         $_SESSION['cart'][$key] = $_SESSION['cart'][$key] + $value;
        }
    }
}
// if this is an update operation
// replace quantities in shopping cart with values entered
else if ($_POST['update'])
{
    foreach ($_POST['u_qty'] as $key => $value)
    {
        // if the value is empty, 0 or negative
        // don't bother changing the cart
        if ($value != " " && $value >= 0)
        {
            $_SESSION['cart'][$key] = $value;
        }
    }
}

// if this is a clear operation
// reset the session and the cart
// destroy all session data
else if ($_POST['clear'])
{
    $_SESSION = array();
    session_destroy();
}

?>

<html>
<head>
    <title>Shopping cart</title>
</head>
<body>

<h2>Catalog</h2>
Please add items from the list below to your shopping cart.
<form action="<?php $_SERVER['PHP_SELF'] ?>" method="POST">
<table border="0" cellspacing="10">
<?php
// print items from the catalog for selection
foreach ($catalog as $key => $value)
{
    echo '<tr><td colspan=2>';
    echo '<b>', $value['desc'], '</b>';
    echo '</td></tr>';
    echo '<tr><td>';
    echo 'Price per unit: ', $catalog[$key]['price'];
    echo '</td><td>Quantity: ';
    echo '<input size="4" type="text" name="a_qty[', $key, ']">';
    echo '</td></tr>';
}
?>
<tr>
<td colspan="2">
<input type="submit" name="add" value="Add items to cart">
</td>
</tr>
</table>

<hr />
<hr />

<h2>Shopping cart</h2>

<table width="100%" border="0" cellspacing="10">
<?php
// initialize a variable to hold total cost
$total = 0;
// check the shopping cart
// if it contains values
// look up the SKUs in the $catalog array
// get the cost and calculate subtotals and totals
if (is_array($_SESSION['cart']))
{
    foreach ($_SESSION['cart'] as $key => $value)
    {
        // only display items that have been selected
        // that is, quantities > 0
        if ($value > 0)
        {
            $subtotal = $value * $catalog[$key]['price'];
            $total += $subtotal;
            echo '<tr><td>';
            echo '<b>', $value, ' unit(s) of ', $catalog[$key]['desc'], '</b>';
            echo '</td><td>';
            echo 'New quantity: <input size="4" type="text" name="u_qty[', $key, ']">';
            echo '</td></tr>';
            echo '<tr><td>';
            echo 'Price per unit: ', $catalog[$key]['price'];
            echo '</td><td>';
            echo 'Sub-total: ', sprintf("%0.2f", $subtotal);
            echo '</td></tr>';
        }
    }
}
?>

<tr>
<td><b>Total</b></td>
<td><b><?php echo sprintf("%0.2f", $total) ?></b></td>
</tr>

<tr>
<td><input type="submit" name="update" value="Update cart"></td>
<td><input type="submit" name="clear" value="Clear cart"></td>
</tr>
</table>
</form>
</body>
</html>

大概就是這樣,最後有什麼問題或意見請指教。
posted at 05/12/18 18:19 | 技术文摘 - PHP | 浏览(252) | 引用(1) | 评论



      << prev    1  2  3  4    next >>