加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

webservice的调用

发布时间:2020-12-16 23:09:26 所属栏目:安全 来源:网络整理
导读:首先说明一下,这个小程序是我自己用PHP写成的一个简单的webservice系统,包括服务端的程序和客户端的程序,无论是服务端还是客户端在使用起来都非常的简单方便,也可以很方便的移植到自己的项目里,我自己也已经在稍微改造后用在了自己的项目里,应用到生产
首先说明一下,这个小程序是我自己用PHP写成的一个简单的webservice系统,包括服务端的程序和客户端的程序,无论是服务端还是客户端在使用起来都非常的简单方便,也可以很方便的移植到自己的项目里,我自己也已经在稍微改造后用在了自己的项目里,应用到生产环境2个多月以来都很稳定,没有出过什么问题。?

这个简单的webservice小程序有以下几个优点:?
1. 简单、易用,几乎没有什么学习成本?
2. 可扩展性很强,因为简单,所以你可以在这个基础上扩展出很多的东西,比如返回的数据格式上可以加上xml的支持等,这个就需要自己动手了?
3. 数据传输量小,服务端到客户端的数据传输采用gzip压缩的方式,极大的减小了数据的体积,我自己做的测试是,一份4.7M的html数据在压缩后只有113K?
4. 有一定的安全性,首先服务端和客户端之间的通讯会有密钥机制,同时又采取限定IP的方式保护了接口的安全。
当然,也有缺点:比如程序过于简单,没有对安全性和数据过过多的校验,这个在应用到生产环境之前一定要记得加强一下;客户端到服务端的请求默认采用get形式,传输的数据量有限,这个我会考虑在以后的改进中改为post,同时数据也采用gzip压缩以后传输。?
好了,言归正传,下面介绍一下代码本身:?
首先是服务端,服务端有一个主要的class组成:apiServer.php?
Php代码??

收藏代码

  1. <?php??
  2. /**?
  3. ?*?apiServer.php?
  4. ?*?
  5. ?*?webservice主类?
  6. ?*?@filename?apiServer.php?
  7. ?*?@version??v1.0?
  8. ?*?@update???2011-12-22?
  9. ?*?@author???homingway?
  10. ?*?@contact??homingway@gmail.com?
  11. ?*?@package??webservice?
  12. ?*/??
  13. define('API_AUTH_KEY',??'i8XsJb$fJ!87FblnW');??
  14. class?apiServer{??
  15. ??
  16. ????//请求参数??
  17. ????public?$request?=?array();??
  18. //是否ip限制??
  19. public?$ip_limit?=?true;??
  20. //允许访问的IP列表??
  21. public?$ip_allow?=?array('127.0.0.1','192.168.0.99');??
  22. public?$default_method?=?'welcome.index';??
  23. public?$service_method?=?//私有静态单例变量??
  24. private?static?$_instance?=?null;??
  25. ?????*?构造方法,处理请求参数?
  26. ?????*/??
  27. function?__construct(){??
  28. ????????$this->dealRequest();??
  29. ????}??
  30. ?????*?单例运行?
  31. public?static?function?getInstance(){??
  32. ????????if(self::$_instance?===?null){??
  33. ????????????self::$_instance?=?new?self();??
  34. ????????}??
  35. return?self::$_instance;??
  36. ?????*?运行?
  37. function?run(){??
  38. ????????//授权??
  39. if(!$this->checkAuth()){??
  40. ????????????exit('3|Access?Denied');??
  41. ????????$this->getApiMethod();??
  42. include_once(API_SERVICE_PATH.'/'.$this->service_method['service'].'.php');??
  43. ????????$serviceObject?=?new?$this->service_method['service'];??
  44. if($this->request['param']){??
  45. ????????????$result?=?call_user_func_array(array($serviceObject,$this->service_method['method']),$this->request['param']);??
  46. ????????}?else?{??
  47. ????????????$result?=?call_user_func($this->service_method['method']));??
  48. if(is_array($result)){??
  49. ????????????$result?=?json_encode($result);??
  50. ????????$result?=?gzencode($result);??
  51. ????????exit($result);??
  52. ?????*?检查授权?
  53. function?checkAuth(){??
  54. //检查参数是否为空??
  55. if(!$this->request['time']?||?!$this->request['method']???||?!$this->request['auth']){??
  56. ????????????return?false;??
  57. //检查auth是否正确??
  58. ????????$server_auth?=?md5(md5($this->request['time'].'|'.$this->request['method'].'|'.API_AUTH_KEY));??
  59. if($server_auth?!=?$this->request['auth']){??
  60. //ip限制??
  61. if($this->ip_limit){??
  62. ????????????$remote_ip?=?$this->getIP();??
  63. ????????????$intersect?=?array_intersect($remote_ip,$this->ip_allow);??
  64. if(emptyempty($intersect)){??
  65. ???????????????? ????????????}??
  66. return?true;??
  67. ?????*?获取服务名和方法名?
  68. function?getApiMethod(){??
  69. if(strpos($this->request['method'],?'.')?===?false){??
  70. ????????????$method?=?$this->default_method;??
  71. ????????????$method?=?$this->request['method'];??
  72. ????????$tmp?=?explode('.',?$method);??
  73. ????????$this->service_method?=?array('service'=>$tmp[0],'method'=>$tmp[1]);??
  74. return?$this->service_method;??
  75. ?????*?获取和处理请求参数?
  76. function?dealRequest(){??
  77. ????????$this->request['time']?=?$this->_request('time');??
  78. ????????$this->request['method']?=?$this->_request('method');??
  79. ????????$this->request['param']?=?$this->_request('param');??
  80. ????????$this->request['auth']?=?$this->_request('auth');??
  81. ????????????$this->request['param']?=?json_decode(urldecode($this->request['param']),true);??
  82. ?????*?获取request变量?
  83. ?????*?@param?string?$item?
  84. function?_request($item){??
  85. return?isset($_REQUEST[$item])???trim($_REQUEST[$item])?:?'';??
  86. ?????*?设置IP限制?
  87. ?????*?@param?bool?$limit?
  88. function?setIPLimit($limit=true){??
  89. ????????$this->ip_limit?=?$limit;??
  90. ?????*?获取客户端ip地址?
  91. function?getIP(){??
  92. ????????$ip?=?if(isset($_SERVER['REMOTE_ADDR'])){??
  93. ????????????$ip[]?=?$_SERVER['REMOTE_ADDR'];??
  94. if(isset($_SERVER['HTTP_VIA'])){??
  95. ????????????$tmp?=?explode(',?',$_SERVER['HTTP_X_FORWARDED_FOR']);??
  96. ????????????$ip?=?array_merge($ip,$tmp);??
  97. ????????$ip?=?array_unique($ip);??
  98. return?$ip;??
  99. }??

然后在服务端的入口文件中调用该class,并启动服务即可,如:?
?*?server.php?
  • ?*?自定义数据接口的入口?
  • ?*?@filename?server.php?
  • //API的根目录??
  • define('API_PATH',dirname(__FILE__));??
  • //服务目录??
  • define('API_SERVICE_PATH',API_PATH.'/service');??
  • define('API_LIB_PATH',??API_PATH.'/lib');??
  • //服务核心class??
  • include_once(API_LIB_PATH.'/apiServer.php');??
  • //运行??
  • apiServer::getInstance()->run();??

  • 然后创建一个service的目录,里面就是自己的接口class,如welcome.php:?
    ?*?welcome.php?
  • ?*?功能代码?
  • ?*?@filename?welcome.php?
  • class?welcome{??
  • function?index(){??
  • return?'hello?service';??
  • 下面是客户端的主程序:apiClient.php?
    ?*?apiClient.php?
  • ?*?webservice客户端程序?
  • ?*?@filename?apiClient.php?
  • class?apiClient{??
  • function?send($url,$method,$param=array()){??
  • ????????$time?=?time();??
  • ????????$auth?=?md5(md5($time.'|'.$method.'|'.API_AUTH_KEY));??
  • if(!is_array($param)?||?emptyempty($param)){??
  • ????????????$json_param?=?'';??
  • ????????????$json_param?=?urlencode(json_encode($param));??
  • ????????$api_url?=?$url.'?method='.$method.'&time='.$time.'&auth='.$auth.'&param='.$json_param;??
  • ????????$content?=?file_get_contents($api_url);??
  • if(function_exists('gzdecode')){??
  • ????????????$content?=?gzdecode($content);??
  • ????????????$content?=?self::gzdecode($content);??
  • return?$content;??
  • function?gzdecode($data)?{??
  • ????????$len?=?strlen?(?$data?);??
  • if?($len?<?18?||?strcmp?(?substr?(?$data,?0,?2?),?"x1fx8b"?))?{??
  • return?null;?//?Not?GZIP?format?(See?RFC?1952)??
  • ????????$method?=?ord?(?substr?(?$data,?2,?1?)?);?//?Compression?method??
  • ????????$flags?=?ord?(?substr?(?$data,?3,0); padding:0px; margin:0px; width:auto; border:0px">//?Flags??
  • if?($flags?&?31?!=?$flags)?{??
  • ????????????//?Reserved?bits?are?set?--?NOT?ALLOWED?by?RFC?1952??
  • return?null;??
  • //?NOTE:?$mtime?may?be?negative?(PHP?integer?limitations)??
  • ????????$mtime?=?unpack?(?"V",?substr?(?$data,?4,?4?)?);??
  • ????????$mtime?=?$mtime?[1];??
  • ????????$xfl?=?substr?(?$data,?8,?1?);??
  • ????????$os?=?substr?(?$data,250); line-height:18px"> ????????$headerlen?=?10;??
  • ????????$extralen?=?0;??
  • ????????$extra?=?"";??
  • if?($flags?&?4)?{??
  • //?2-byte?length?prefixed?EXTRA?data?in?header??
  • if?($len?-?$headerlen?-?2?<?8)?{??
  • return?false;?//?Invalid?format??
  • ????????????$extralen?=?unpack?(?"v",?2?)?);??
  • ????????????$extralen?=?$extralen?[1];??
  • if?($len?-?$headerlen?-?2?-?$extralen?<?8)?{??
  • ????????????$extra?=?substr?(?$data,?10,?$extralen?);??
  • ????????????$headerlen?+=?2?+?$extralen;??
  • ????????$filenamelen?=?0;??
  • ????????$filename?=?"";??
  • if?($flags?&?8)?{??
  • //?C-style?string?file?NAME?data?in?header??
  • if?($len?-?$headerlen?-?1?<?8)?{??
  • ????????????$filenamelen?=?strpos?(?substr?(?$data,?8?+?$extralen?),?chr?(?0?)?);??
  • if?($filenamelen?===?false?||?$len?-?$headerlen?-?$filenamelen?-?1?<?8)?{??
  • ????????????$filename?=?substr?(?$data,?$headerlen,?$filenamelen?);??
  • ????????????$headerlen?+=?$filenamelen?+?1;??
  • ????????$commentlen?=?0;??
  • ????????$comment?=?"";??
  • if?($flags?&?16)?{??
  • //?C-style?string?COMMENT?data?in?header??
  • ????????????$commentlen?=?strpos?(?substr?(?$data,?8?+?$extralen?+?$filenamelen?),85); font-weight:bold">if?($commentlen?===?false?||?$len?-?$headerlen?-?$commentlen?-?1?<?8)?{??
  • //?Invalid?header?format??
  • ????????????$comment?=?substr?(?$data,?$commentlen?);??
  • ????????????$headerlen?+=?$commentlen?+?1;??
  • ????????$headercrc?=?"";??
  • if?($flags?&?1)?{??
  • //?2-bytes?(lowest?order)?of?CRC32?on?header?present??
  • ????????????$calccrc?=?crc32?(?substr?(?$data,?$headerlen?)?)?&?0xffff;??
  • ????????????$headercrc?=?unpack?(?"v",250); line-height:18px"> ????????????$headercrc?=?$headercrc?[1];??
  • if?($headercrc?!=?$calccrc)?{??
  • //?Bad?header?CRC??
  • ????????????$headerlen?+=?2;??
  • //?GZIP?FOOTER?-?These?be?negative?due?to?PHP's?limitations??
  • ????????$datacrc?=?unpack?(?"V",?-?8,250); line-height:18px"> ????????$datacrc?=?$datacrc?[1];??
  • ????????$isize?=?unpack?(?"V",?-?4?)?);??
  • ????????$isize?=?$isize?[1];??
  • //?Perform?the?decompression:??
  • ????????$bodylen?=?$len?-?$headerlen?-?8;??
  • if?($bodylen?<?1)?{??
  • //?This?should?never?happen?-?IMPLEMENTATION?BUG!??
  • ????????$body?=?substr?(?$data,?$bodylen?);??
  • ????????$data?=?"";??
  • if?($bodylen?>?0)?{??
  • switch?($method)?{??
  • case?8?:??
  • ????????????????????//?Currently?the?only?supported?compression?method:??
  • ????????????????????$data?=?gzinflate?(?$body?);??
  • ????????????????????break;??
  • default?:??
  • //?Unknown?compression?method??
  • //?I'm?not?sure?if?zero-byte?body?content?is?allowed.??
  • //?Allow?it?for?now...??Do?nothing...??
  • //?Verifiy?decompressed?size?and?CRC32:??
  • //?NOTE:?This?may?fail?with?large?data?sizes?depending?on?how??
  • //???????PHP's?integer?limitations?affect?strlen()?since?$isize??
  • //???????may?be?negative?for?large?sizes.??
  • if?($isize?!=?strlen?(?$data?)?||?crc32?(?$data?)?!=?$datacrc)?{??
  • //?Bad?format!??Length?or?CRC?doesn't?match!??
  • return?$data;??
  • 使用起来非常简单,下面是一个调用程序:?
    ?*?demo.php?
  • ?*?客户端调用示例?
  • ?*?@filename?demo.php?
  • include_once('../client/apiClient.php');??
  • $server_uri?=?'http://localhost/webservice/server/server.php';??
  • print_r(apiClient::send($server_uri,'welcome.index'));??

  • 本文所涉及到的所有代码及主程序我都打包到下面的zip文件中,可以直接下载,有什么疑问可以直接在下面留言回复。?

    (编辑:李大同)

    【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

      推荐文章
        热点阅读