开发者社区> 技术小甜> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

实践基于REST风格的Webservice(PHP,C#)

简介:
+关注继续查看


概念:

WEB服务的风格,从维基百科上查了一下,有不下十几种,但是比较常用的就是REST和RPC。其中,基于SOAP协议的Webservice就是RPC风格的。

REST全称Representational State Transfer。它是基于无状态的,cs结构的,可以缓存的通信协议。事实上,它是使用 HTTP协议的。某些观点来看,互联网本身就是基于HTTP的,因此也可以认为是一种基于REST风格的Webservice。REST风格的Webservice对于SOAP,CORBA(一种和SOAP互相竞争的协议)来说,属于轻量级。请求较之于也比较简单。比如,用SOAP的Webservice的请求可能是如下这样的一个XML,有用的信息都被包括在冗余的信息中:

<?xml version="1.0"?>

<soap:Envelope

xmlns:soap="http://www.w3.org/2001/12/soap-envelope"

soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">

<soap:body pb="http://www.acme.com/phonebook">

 <pb:GetUserDetails>

  <pb:UserID>12345</pb:UserID>

 </pb:GetUserDetails>

</soap:Body>

</soap:Envelope>


而使用REST的请求就很简单,只是一个URL地址:http://www.acme.com/phonebook/UserDetails/12345,只需要使用浏览器就能验证这个REST的Webservice是否正常。HTTP的请求方式有多种,GET,POST,PUT,PATCH,DELETE。REST同样可以利用这些请求方式。REST的Webservice的响应通常是一个XML文件,但是和SOAP不同的是,REST并不一定需要响应返回XML文件,它也可以是CSV格式或者Json格式。

很多公司都采用REST风格的Webservice,比如 Google Glass API,Twitter,Yahoo,Flickr,Amazon等。比如Google有一个Webservice,Google Maps API,它提供2种输出格式,JSON和XML。地址分别是http://maps.googleapis.com/maps/api/geocode/json?parameters和http://maps.googleapis.com/maps/api/geocode/xml?parameters

该服务的具体使用方法和参数满可以查阅https://developers.google.com/maps/documentation/geocoding/?hl=zh-CN&csw=1#XML

演示:

下面演示一个基于PHP语言开发的REST风格的webservice。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
<?php
switch($_SERVER['REQUEST_METHOD'])
{
    case 'GET':
        $id=$_GET["id"];
        $arrayid explode(","$id);
        search($arrayid);
        break;
    case 'POST':
        $id=$_POST["id"];
        $username=$_POST["username"];
        $sex=$_POST["sex"];
        $age=$_POST["age"];
                                       
        add($id,$username,$sex,$age);
        break;
    default:
        exit();
}
function search($arrayid)
{
    $users=getCsvFile("example.csv");
    $string="";
    foreach($users as $a)
    {
        $id=$a[0];
        if(in_array($id,$arrayid))
        {
            $string.= <<<EOF
    <user id="$a[0]">
        <name>$a[1]</name>
        <sex>$a[2]</sex>
        <age>$a[3]</age>
    </user>
EOF;
        }
    }
    $string="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
            ."<data>\r\n"
            .$string
            ."</data>";
                                   
    header("Content-type:application/xml");
    print($string);
                                   
}
function add($id,$username,$sex,$age)
{
    $users=getCsvFile("example.csv");
    $string="$id,$username,$sex,$age";
                                   
    WriteLinetxt($string,"example.csv");
                                   
    $string="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
            ."<return>\r\n"
            ."  <status>0</status>\r\n"
            ."</return>\r\n";
                                   
    header("Content-type:application/xml");
    print($string);
                                   
}
function getCsvFile($filepath)
    {
        $handle=null;
        $returnvalue=array();
        try
        {
            $handle fopen($filepath,"r");
            while ($data fgetcsv($handle, 1000, ","))
            {
                array_push($returnvalue,$data);
            }
            fclose($handle);
        }
        catch(Exception $e)
        {
            fclose($handle);
            $handle=null;
            die("Error!: ".$e->getMessage()."<br/>");
        }
                                       
        return $returnvalue;
    }
function WriteLinetxt($content,$filename)
{
        file_put_contents($filename$content."\r\n",FILE_APPEND);
}
?>

代码说明:

上述代码,根据请求的方式是POST还是GET来区分,如果是GET的话,则需带上查询的ID。服务会返回一个Content-type为application/xml的一份xm文档。如果是POST的话,则会把相应的POST进来的值写入到数据库。

本例中,数据库只是简单的采用CSV文件,即用逗号分割数据的文本文件。数据文件如下:

CBD247FF7AF9473193DC06EB24DBCCC8

由于REST风格的web服务可以通过浏览器验证,因此可以输入url地址测试。本例中没有采用url重写,如果使用url重写的话,服务地址会更友好。

D87BE31CF24D416BA901BA11EF15A2A6

服务部署好之后,就可以调用了。在PHP中,可以通过simplexml_load_file方法,get到这个xml文件。

1
2
3
4
5
<?php
$url="http://localhost:8080/b.php?id=1001,1003,1004";
$response=simplexml_load_file($url);
var_dump($response);
?>

74A2BDE9531F4A879C284A805D575126

通过var_dump,可以看到获得的直接是一个SimpleXMLElement对象,当然你也可以把它转换成string对象。

下面用php代码实现模拟POST数据。PHP常用的模拟POST动作的方法有3种,分别为Curl、socket、file_get_contents,这里还是采用file_get_contents方法。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
$url="http://localhost:8080/b.php";
$data array
(
    'id' => '1990',
    'username' => '小张',
    'sex' => '男',
'age'=>'20'
);
$post_string=http_build_query($data);
$context array(
    'http' => array(
        'method' => 'POST',
'header'=>'content-type: application/x-www-form-urlencoded',
        'content' => $post_string)
    );
$stream_context = stream_context_create($context);
$response file_get_contents($url, false, $stream_context);
$xml=simplexml_load_string($response);
var_dump($xml);
?>

代码中,模拟了POST提交,并且获得了返回的string,再把string转成了SimpleXMLElement对象。而且数据库中数据也已经写入。

5ABB6024DDF8491FAE0A051F8E524C15

C#版本访问:

C#也可以通过代码调用PHP写的REST风格的Webservice。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
class Program
   {
       static void Main(string[] args)
       {
           string[] paramName = { "id" };
           string[] paramVal = { "1001,1004" };
           var p = HttpGet("http://localhost:8080/b.php", paramName, paramVal);
           Console.WriteLine(p);
           Console.WriteLine("-------------------------------");
           string[] paramName1 = { "id""username""sex""age" };
           string[] paramVal1 = { "1030""tom""男""23" };
           var p1 = HttpPost("http://localhost:8080/b.php", paramName1, paramVal1);
           Console.WriteLine(p1);
       }
       static string HttpGet(string url, string[] paramName, string[] paramVal)
       {
           StringBuilder paramz = new StringBuilder();
           for (int i = 0; i < paramName.Length; i++)
           {
               paramz.Append(paramName[i]);
               paramz.Append("=");
               paramz.Append(HttpUtility.UrlEncode(paramVal[i]));
               paramz.Append("&");
           }
           url += "?" + paramz.ToString();
           HttpWebRequest req = WebRequest.Create(url) as HttpWebRequest;
           string result = null;
           using (HttpWebResponse resp = req.GetResponse() as HttpWebResponse)
           {
               StreamReader reader = new StreamReader(resp.GetResponseStream());
               result = reader.ReadToEnd();
           }
           return result;
       }
       static string HttpPost(string url, string[] paramName, string[] paramVal)
       {
           HttpWebRequest req = WebRequest.Create(new Uri(url)) as HttpWebRequest;
           req.Method = "POST";
           req.ContentType = "application/x-www-form-urlencoded";
           // Build a string with all the params, properly encoded.
           // We assume that the arrays paramName and paramVal are
           // of equal length:
           StringBuilder paramz = new StringBuilder();
           for (int i = 0; i < paramName.Length; i++)
           {
               paramz.Append(paramName[i]);
               paramz.Append("=");
               paramz.Append(HttpUtility.UrlEncode(paramVal[i]));
               paramz.Append("&");
           }
           // Encode the parameters as form data:
           byte[] formData = UTF8Encoding.UTF8.GetBytes(paramz.ToString());
           req.ContentLength = formData.Length;
           // Send the request:
           using (Stream post = req.GetRequestStream())
           {
               post.Write(formData, 0, formData.Length);
           }
           // Pick up the response:
           string result = null;
           using (HttpWebResponse resp = req.GetResponse() as HttpWebResponse)
           {
               StreamReader reader = new StreamReader(resp.GetResponseStream());
               result = reader.ReadToEnd();
           }
           return result;
       }
   }

F8FED7F3BB7C4808801FE1FA3AC1C220

参考文档:

http://geeknizer.com/rest-vs-soap-using-http-choosing-the-right-webservice-protocol/

http://msdn.microsoft.com/zh-cn/magazine/dd942839.aspx

http://www.gen-x-design.com/archives/create-a-rest-api-with-php/

http://rest.elkstein.org/2008/02/what-is-rest.html

















本文转自cnn23711151CTO博客,原文链接: http://blog.51cto.com/cnn237111/1285298,如需转载请自行联系原作者



版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
x3d
[转]拙议REST及其在PHP中的现状
本文并不想从头介绍REST,只是想举例说明在HTTP中使用REST需要注意的问题:先来看看人们对REST的困惑: REST长啥样? 最一般的REST例子,类似下面的样子: POST   /articles     ...
986 0
【第二届PHP全球开发者大会】MySQL中文网站创始人叶金荣:程序猿都该知道的MySQL秘籍
5月14-15日的第二届2016PHP全球开发者大会在北京国际会议中心举行。MySQL中文网站创始人、Oracle MySQL ACE叶金荣带来的分享是《程序猿都该知道的MySQL秘籍》,他主要介绍了MySQL的优化秘籍,并对InnoDB引擎做了深入的讲解;同时与大家分享了在MySQL的优化过程中所
3628 0
MySql - InnoDB - 事务 , Php版
(出处:http://www.cnblogs.com/linguanh/)   1,前序   由于要重构APP(社交类) 服务端接口的部分代码,故接触到了 innoDB,以及事务这个词,下面主要是以例子的形式显示它的用法,理论的东西不过多讲述。
1019 0
centos下 Apache、php、mysql默认安装路径
apache: 如果采用RPM包安装,安装路径应在 /etc/httpd目录下 apache配置文件:/etc/httpd/conf/httpd.conf Apache模块路径:/usr/sbin/apachectl web目录:/var/www/html 如果采用源代码安装,一般默认安装在/usr/local/apache2目录下 php: 如果采用RPM包安装,安装路
3114 0
+关注
文章
问答
文章排行榜
最热
最新
相关电子书
更多
PHP与APM_技术内幕和最佳实践
立即下载
PHP安全开发_从白帽角度做安全
立即下载
阿里云栖开发者沙龙PHP技术专场-深入浅出网络编程与swoole内核-吴镇宇
立即下载