龙军
摘要:该文在分析分布式异構系统及面向服务架构基础上,对WebService和Restful WebService进行比较,研究基于PHP+Apache的分布式系统构架,最后从数据库操作、Restful WebService的制作、HTML5前端、Android客户端等方面进行系统的研究和模型设计。
关键词:分布式; PHP; WebService; Restful WebService
中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2018)35-0087-03
随着计算机软硬件及网络技术的发展,软件系统规模、应用领域、实现功能不断扩大,基于资源共享、高可用和并行处理的分布式异构系统成为解决复杂应用的有力工具。
1 分布式异构系统(DHS)及面向服务架构(SOA)概述
分布式系统是基于网络具有高内聚性和透明性的软件系统,异构系统由不同硬件设备、操作系统、应用软件、数据等构成,通过消息中间件在不同应用间提供统一运行的框架和接口,实现跨平台数据传输,共同完成应用任务,并通过动态增加或减少业务端,使业务系统具有良好的动态负载伸缩能力。
面向服务架构以基于XML/SOAP/Web Service/SCA/SDO/UDDI标准、可重用数据、业务服务组件为基础,围绕业务流程,对业务逻辑进行高度抽象的架构模型和软件开发方式,将异构平台上不同应用的功能组件封装成有良好定义、与平台无关、标准、可拼接拆卸、可复用的服务,形成松散耦合的软件系统。功能为独立服务,通过如REST、SOAP等远程通信协议,借助中间件来实现SOA需求。
2 WebService和Restful WebService的比较
WebService是跨编程语言及操作系统平台的远程调用技术,为网络应用开发和使用提供统一的编程模型,通常被定义为一组模块化API供外部使用,有基于WSDL、UDDI的简单对象访问协议(SOAP)方式和REST方式两种。
SOAP协议方式的消息通过增加特定HTTP消息头统一内容格式,用XML格式封装数据,用HTTP协议进行传输,用XSD定义标准的数据类型,将所有使用的数据类型均转换为XSD类型。WSDL用XML描述WebService及其函数、参数和返回值,保存在Web服务器上,通过URL访问,用UDDI发现WebService。
REST是一面向资源的架构风格,是一组架构约束条件和原则,满足约束条件和原则的程序就是RESTful。REST专门针对网络应用设计和开发,降低开发复杂性,提高系统可伸缩性,将网络上所有事物都抽象成有唯一标识的资源。REST所有操作均无状态,遵循CRUD原则,只需创建POST、获取GET、更新PUT和删除DELETE四种行为就可完成相关操作和处理,通过统一简短的资源标识符(URI)来识别和定位资源,并通过HTTP规范资源操作。
3 基于PHP的分布式系统构架设计
PHP是开源跨平台的服务器端嵌入式脚本语言,已发展成完整的面向对象程序设计语言,语法简单、强大的数据库支持、在服务器端执行、会将用户常访问的程序驻留内存、效率高,得到广泛应用。
本模型基于PHP+Apache+MySql,用PHP的类完成数据增删改查等操作,用SOAP WebService和Restful WebService对前端请求进行合法判断,调用类进行数据处理,返回JSON格式数据给前端,前端为Web应用、移动端的Native App和Web App应用,在本模型中原生程序基于Android、Web App用HTML5。
4 数据库操作类
PHP数据对象PDO扩展定义了轻量级的接口访问数据库,提供了一数据访问的抽象,对所有数据库均可用相同的函数/方法来操作。在类的构造方法__construct()中设置服务器地址、数据库名以及登录名和密码。创建连接数据库函数conn()连接服务器并选择数据库:
$link=new PDO("mysql:host=$hostname;dbname=$db_name", $username,$password);
通过传入sql语句,完成表的增删改函数zcg($sql):$this→link→exec($sql)。
[传入sql语句查询一条记录 传入sql语句查询符合条件的多条记录 $result=$this->link->query($sql);
if($row=$result->fetch_object()){
$a=array('id'=>$row->Id,'yhm'=>$row->yhm,'mm'=>$row->mm);
$json=json_encode($a);
}else
$json='{"id":"0"}}'; $result=$this->link->query($sql);
$num=$result->num_rows;
$a=array();
while($row=$result->fetch_object()){
$b=array('id'=>$row->Id,'yhm'=>$row->yhm,'mm'=>$row->mm);
$a[$i]=json_encode($b);
$i=$i+1;} ]
5 Restful WebService
1) RESTful 基礎类:新建一个RESTful基类,用于处理响应请求的HTTP状态码。
[private $httpVersion = "HTTP/1.1";
public function setHttpHeaders($contentType, $statusCode){
$statusMessage = $this -> getHttpStatusMessage($statusCode);
header($this->httpVersion. " ". $statusCode ." ". $statusMessage);
header("Content-Type:". $contentType);}
public function getHttpStatusMessage($statusCode){
$hs = array(100 => 'Continue', 101 => 'Switching Protocols', 200 => 'OK',...);
return ($hs[$statusCode]) ? $hs[$statusCode] : $status[500];} ]
2) RESTful WebService处理类:新建一个RESTful基类的子类,根据接收到的Content-Type,将Request类返回的数据转换为对应的格式,加上header后输出HTTP 状态码及数据。
[多条记录getYhbRows($kw) 一条记录getYhbRow($id) $yhb = new yhb();
$sql="select * from yhb where yhm like ‘%”+$key+”% order by Id desc";
$rawData = $yhb->getRows($sql);
if(empty($rawData)) {
$sCode = 404;
$rawData = array('error' => '无记录!');
} else $sCode = 200;
$rcType = $_SERVER['HTTP_ACCEPT'];
$this ->setHttpHeaders($rcType, $sCode);
echo $rawData; $yhb = new yhb();
$sql="select * from yhb where id="+$id;
$rawData = $yhb->getRow($sql);
if(empty($rawData)) {
$sCode = 404;
$rawData = array('error' => '无记录!');
} else
$sCode = 200;
$rcType= $_SERVER['HTTP_ACCEPT'];
$this ->setHttpHeaders($rcType, $sCode);
echo $rawData; ]
3) RESTful WebService控制器:包含一数据操作的Request类,接收到URL的数据后,根据请求URL的GET、POST、PUT、PATCH、DELETE方式对数据进行相应的增删改查操作,并返回操作后的结果。要注意的是在PHP文件开始时允许跨域。
[header("Access-Control-Allow-Origin:*");
$method=$_SERVER['REQUEST_METHOD'];
$view = "";
if(isset($_GET["view"])) $view = $_GET["view"];
$yhbHandler = new YHBHandler();
if($view=="all") $yhbHandler ->getYhbRows();
else if($view=="single") $yhbHandler ->getYhbRow($_GET["id"]); ]
4) RESTful Services URI映射:设置一直观简短的资源地址,在配置文件htaccess中设置相应的Rewrite规则实现URL重写(rewrite)与重定向(redirect)。
[# 开启 rewrite 功能
Options +FollowSymlinks
RewriteEngine on
# 重写规则
RewriteRule ^list/$ YhbController.php?view=all [nc,qsa]
RewriteRule ^read/([0-9]+)/$ YhbController.php?view=single&id=$1 [nc,qsa] ]
6 基于HTML5的Web端和移动端
Web应用及移动端的Web App通过jQuery的post、get方法进行数据处理及交互。
[GET方式 POST方式 $.get("网址/read/"+$("#id").val()+"/",
function(data){
json=JSON.parse(data);
$("#xs").html("id=" + json.id + "<br>用戶名=" + json.yhm + "<br>密码=" + json.mm);
},"json"); $.post("网址/list/",{kw:$("#kw").val()},
function(data){
var a1=JSON.parse(data);
if(a1.length>0){var str="";
for(var i=0;i<a1.length;i++){
var a=JSON.parse(a1[i]);
str+="id:"+a.id+",用户名:"+a.yhm+",密码:"+a.mm+"<br>";}
$("#xs").html(str);}},"json"); ]
7 Android端原生应用
在Android中可用HttpPost和HttpGet封装post请求和get请求,用HttpClient的excute()发送post请求并返回服务器响应数据。用HttpResponse的getAllHeaders()、getHeaders(String name)等获取服务器的响应头,用getEntity()获取包装有服务器响应内容的HttpEntity对象,程序通过该对象获取服务器的响应内容。
[GET方式 POST方式 String urls="网址/read/"+id+"/";
HttpClient hc=new DefaultHttpClient(); String urls="网址/list/";
HttpPost hp=new HttpPost(urls);
List<NameValuePair> p=new ArrayList<NameValuePair>(); HttpGet hg=new HttpGet(urls);
HttpResponse hr=hc.execute(hg);
HttpEntity he=hr.getEntity();
r=EntityUtils.toString(he,"utf-8"); p.add(new BasicNameValuePair("kw",e.getText().toString()));
hp.setEntity(new UrlEncodedFormEntity(par,"utf-8"));
HttpClient hc=new DefaultHttpClient();
HttpResponse hr=hc.execute(hp);
HttpEntity he=hr.getEntity();
r=jtos(EntityUtils.toString(he,"utf-8")); ]
在模型应用间采用JSON格式数据进行传输,JSON是轻量级的数据交换语言,JSON和XML均有相同的数据可读性和丰富的解析手段,JSON相较XML数据体积小、与JavaScript交互更方便、速度快,但JSON的数据描述性差。
RESTful架构层次分明、结构清晰,轻量级JSON格式在数据交换中易访问、可扩展,能轻易实现多种数据、多种服务的聚合,提高了软件系统的开发效率,基于PHP的分布式应用系统开发应用面将越来越广。
参考文献:
[1] 王非. RESTful Web Services在信息系统中的应用[J]. 计算机系统应用,2013(22).
[2] 万为清. WebService技术在分布式开发中的应用与实现[J]. 电脑编程技巧与维护,2017(18).
[3] 徐晓琴. 基于WebService技术的SAP接口实现[J]. 电脑知识与技术,2018(14).
[4] 张琛. 分布式软件系统交互行为建模、验证与测试[J]. 计算机研究与发展,2015(52).
[5] 黄博怡. Web Services技术手段在异构系统集成中的应用实践[J]. 现代工业经济和信息化,2017(9).
[通联编辑:梁书]