http接口是什么,我一直没找到比较明确的定义(如果有哪位可以提点一下,我将非常感谢),今天就自己来总结一下吧。个人认为,http接口就是一种基于http服务的api,是系统之间交互的一种约定,所谓的web service其实也就是一种http接口,只不过它是比较规范的、通用的。

http接口有什么用,个人体会是,http接口最主要的作用是能够较好地解决不同系统(可能是功能不同、开发语言不同、服务商不同,等等,但都是基于http服务的)之间的交互的需求,比如像微信公众号的各种接口,不管是使用Java开发还是PHP进行开发,不管是A公司在开发还是B公司在开发,也不管是要做商城系统还是做企业宣传网站,都一样可以很好地调用。

接下来就展现一套自己写的简易的http接口,作为自己这段时间学习与实践的一个小总结。这套接口的基本框架,在本人的具体开发实践中是有用到的,目前来看,运行效率和可扩展性还算能满足需要。

下图就是整个框架项目的目录结构

整个接口服务端的处理流程如下:

1、接收并解析请求;

包括检查数据格式、验证签名等。

2、根据请求实例化对应的处理器;

简单工厂模式,映射规则为:接口名称为test,则实例化apis\TestApi类。

3、处理器具体处理请求;

调用处理器的handle()方法,比如userinfo接口,handle()可能就是去数据库中查找响应的user信息。

4、处理器输出响应

调用response()方法。

前面也说了,接口是一种约定,因此发送数据和输出响应都是要遵循这个约定的,一般情况下,约定分为总体约定和具体接口约定两个部分,总体约定如下:

1、以http的post方式提交数据,数据在$_POST中的键名为data;

2、数据提交时需要先后经过json和base64编码,中文需保持原样,输出的响应同样如此;

3、提交数据的格式:

$data = [

'api' => 'userinfo', // 具体接口名称,必须

'noncestr' => '123',// 随机字符串,必须

'serial' => '123', // 调用流水号,必须

'signature' => 'xxx', // 签名,必须

'body' => [

... // 请求详细数据,由具体接口约定,可选

]

];

4、响应数据的格式:

$data = [

'code' => 0, // 状态码,0为调用成功,非0为失败,必须

'serial' => '123', // 调用流水号,必须

'signature' => 'xxx', // 签名,非必须

'body' => [

... // 响应详细数据,由具体接口约定,可选

]

];

以下是各文件的代码:

aHttpApiHandler.php

<?phpnamespace apis;
use libraries\HttpApiUtil;/*** api处理器抽象类*/
abstract class aHttpApiHandler {/*** 请求数据* @var array*/protected $data = [];/*** 处理结果* @var array*/protected $result = [];/*** 处理请求*/abstract function handle();/*** 构造方法* @access public* @param array $data* @return void*/public function __construct($data) {$this->data = $data;}/*** 输出响应* @access public* @return mixed*/public function response() {$result = HttpApiUtil::makeReturn(0, '', $this->data['serial'], $this->result);echo base64_encode(json_encode($result, JSON_UNESCAPED_UNICODE));}
}

TestApi.php

<?phpnamespace apis;/*** test接口*/
class TestApi extends aHttpApiHandler {/*** 处理请求* @access public* @return mixed*/public function handle() {echo '调用' . __CLASS__ . '处理请求', PHP_EOL;}/*** 输出响应* @access public* @return mixed*/public function response() {echo '调用' . __CLASS__ . '处理请求完毕,输出响应', PHP_EOL;}
}

UserinfoApi.php

<?phpnamespace apis;/*** userinfo接口*/
class UserinfoApi extends aHttpApiHandler {/*** 处理请求* @access public* @return mixed*/public function handle() {// 模拟从数据库取得用户信息$id = $this->data['body']['id'];$this->result = ['id' => $id,'name' => 'webmaster','nickname' => 'web管理员']; }
}

common.php

<?php/*** 类自动加载函数*/
function api_autoload($class) {@include $class . '.php';
}// 设置自动加载路径
$includePath = ['apis', 'libraries'];
$includePath = implode(';', array_map(function($v){return ROOT_PATH . '/' . $v;
}, $includePath));
set_include_path($includePath);// 注册自动加载函数
spl_autoload_register('api_autoload');

CurlUtil.php

<?phpnamespace libraries;/*** curl工具类*/
class CurlUtil {/*** 以post方式获取结果* @access public* @param string $url url地址* @param string $data 数据* @throws \Exception* @return string*/public static function doPost($url, $data = null) {// 初始化if (!$ch = curl_init()) throw new \Exception('curl初始化失败');// 设置选项curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);if ($data) {curl_setopt($ch, CURLOPT_POST, 1);curl_setopt($ch, CURLOPT_POSTFIELDS, $data);}$result = curl_exec($ch);if (curl_errno($ch)) throw new \Exception(curl_error($ch));curl_close($ch);return $result;}
}

HttpApiConfig.php

<?phpnamespace libraries;/*** api配置类*/
class HttpAPiConfig {/*** 签名key* @var string*/const KEY = 'key for signature';
}

HttpApiError.php

<?phpnamespace libraries;/*** api错误定义*/
class HttpApiError {/*** 数据格式错误* @var integer*/const INVALID_DATA = 10001;/*** 数据解析错误* @var integer*/const DATA_PARSE_ERROR = 10002;/*** 签名错误* @var integer*/const INVALID_SIGNATURE = 10003;/*** 接口不存在* @var integer*/const INVALID_API = 10004;/*** 无法创建处理器* @var integer*/const CANT_CREATE_HANDLER = 10005;/*** 未知错误* @var integer*/const UNKNOWN_ERROR = 90001;/*** 错误码与错误信息映射* @var array*/private static $errors = [10001 => '数据格式错误',10002 => '数据解析错误',10003 => '签名错误',10004 => '接口不存在',10005 => '无法创建处理器',90001 => '未知错误',];/*** 获取错误信息* @access public* @param integer $code 错误码* @return mixed*/public static function getError($code) {return isset(self::$errors[$code]) ? self::$errors[$code] : false;}
}

HttpApiHandlerFactory.php

<?phpnamespace libraries;/*** api处理器工厂*/
class HttpApiHandlerFactory {/*** 生成api处理器实例* @access public* @param string $data* @throws \Exception* @return \libraries\aHttpApiHandler*/public static function create($data) {$info = HttpApiParser::parse($data);if ($info['code']) {throw new \Exception($info['msg'], $info['code']);}$request = $info['body'];$class = '\\apis\\' . ucfirst(strtolower($request['api'])) . 'Api';try {$rfc = new \ReflectionClass($class);return $rfc->newInstance($request);} catch (\Exception $e) {throw new \Exception(HttpApiError::getError(HttpApiError::CANT_CREATE_HANDLER), HttpApiError::CANT_CREATE_HANDLER);}      }
}

HttpApiParser.php

<?phpnamespace libraries;/*** api请求解析器*/
class HttpApiParser {/*** 解析请求* @access public* @param string $data* @return array*/public static function parse($data) {if (!is_array($data) || !array_key_exists('data', $data)) {return HttpApiUtil::makeReturn(HttpApiError::INVALID_DATA, HttpApiError::getError(HttpApiError::INVALID_DATA));}$request = json_decode(base64_decode($data['data']), true);if (json_last_error()) {return HttpApiUtil::makeReturn(HttpApiError::UNKNOWN_ERROR, HttpApiError::getError(HttpApiError::UNKNOWN_ERROR));}// 检查数据格式if (empty($request['api'])|| empty($request['noncestr'])|| empty($request['serial'])|| empty($request['signature'])) {return HttpApiUtil::makeReturn(HttpApiError::INVALID_DATA, HttpApiError::getError(HttpApiError::INVALID_DATA));}// 检查签名if ($request['signature'] != HttpApiUtil::makeSign($request)) {return HttpApiUtil::makeReturn(HttpApiError::INVALID_SIGNATURE, HttpApiError::getError(HttpApiError::INVALID_SIGNATURE), $request['serial']);}return HttpApiUtil::makeReturn(0, '', $request['serial'], $request);}
}

index.php

<?php// 接收请求use libraries\HttpApiHandlerFactory;
use libraries\HttpApiUtil;define('ROOT_PATH', __DIR__);
include ROOT_PATH . '/common/common.php';// **************************************// 创建处理器
try {$api = HttpApiHandlerFactory::create($_POST);
} catch (\Exception $e) {print_r(HttpApiUtil::makeReturn($e->getCode(), $e->getMessage()));exit();
}// 执行操作
$api->handle();
$api->response();

test.php

<?php// 发起调用use libraries\HttpApiUtil;
use libraries\CurlUtil;define('ROOT_PATH', __DIR__);
include ROOT_PATH . '/common/common.php';// **************************************$url = 'http://api.local.com/index.php';
$data = ['api' => 'test','noncestr' => HttpApiUtil::makeNoncestr(),'serial' => HttpApiUtil::makeSerial(),'body' => []
];
$data['signature'] = HttpApiUtil::makeSign($data);$json = 'data=' . base64_encode(json_encode($data));
try {$response = CurlUtil::doPost($url, $json);echo $response;//  原始输出print_r(json_decode(base64_decode($response), true));
} catch (Exception $e) {echo $e->getMessage();
}

OK,简易的http接口就是这样了,如果要新增一个具体接口,比如查看用户列表,可以考虑新增一个apis\UserlistApi类,继承aHttpApiHandler类并实现相应的方法即可了。

简易http接口实现相关推荐

  1. 简易的服务器接口开发入门教程

    前沿 谷丝小说网 https://www.wayi.info 为了解决服务器接口开发的问题,因此学习了关于Spring Boot的知识,然后再自己摸索总结后台的开发经验.所以这篇文章就是面向搞移动开发 ...

  2. 快捷简易统计图表模型设计与实现

    1. 目的 在系统后台,很多地方都需要以直观的方式呈现相关统计数据,然而总是从查询语句.接口.页面到图表的过程,繁琐费时.对于简单的统计需求,期望建立合适的模型,简化这个过程,并使得整个过程聚焦数据本 ...

  3. pc企业微信协议,企业微信HOOK接口

    pc企业微信hook接口企业微信, 封装成dll,并提供简易的接口给程序调用. 你可以通过扩展 dll 来实现: 监控或收集微信消息 自动消息推送 聊天机器人 社群等管理 //实例 参数名 必选 类型 ...

  4. 抽象类、接口、Objext 详解

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 抽象类 1.1 抽象类的概念 1.2抽象类的语法 1.3 抽象类的特性 1. 抽象类是不能被实例化的 2. 抽象方法是不能实现的 ...

  5. vc++ PC微信 逆向HOOK接口

    企业微信项目地址: https://github.com/smallevilbeast/wxwork_pc_api wechat_pc_api 使用HOOK技术将核心功能封装成dll,并提供简易的接口 ...

  6. 企业微信hook接口,易语言调用

    [介绍] 使用HOOK技术将核心功能封装成dll,并提供简易的接口给支持调用dll的语言使用 目前测试可以使用语言有C/C++,C#,易语言,Python, Java, Go, VB, Delphi ...

  7. python hook pc微信_PC企业微信HOOK接口开源

    介绍 wxwork_pc_api 使用HOOK技术将核心功能封装成dll,并提供简易的接口给支持调用dll的语言使用. 你可以通过扩展 wxwork_pc_api 来实现: 监控或收集企业微信消息 自 ...

  8. 一分钟图表:简易统计图表模型设计与实现

    1. 目的 在系统后台,很多地方都需要以直观的方式呈现相关统计数据,然而总是从查询语句.接口.页面到图表的过程,繁琐费时.对于简单的统计需求,期望建立合适的模型,简化这个过程,并使得整个过程聚焦数据本 ...

  9. PC企业微信HOOK接口开源

    介绍 企微助手VXApi使用HOOK技术将核心功能封装成dll,并提供简易的接口给支持调用dll的语言使用. 你可以通过扩展企微助手VXApi来实现: 监控或收集企业微信消息 自动消息推送 聊天机器人 ...

最新文章

  1. python官网下载步骤2019-2019年python入门到精通(19天全)
  2. python Intel Realsense D435 图像自动采集程序 自动剔除模糊图像
  3. 数据库设计原则与开发规范,你知道多少?
  4. Spark键值对RDD的转化操作
  5. python平均分计算器_招募:基于python的召唤师全时段全技能(含均值AI)计算器全程测试...
  6. Oracle truncate table 与 delete tabel的区别
  7. 蓝桥杯 算法训练 矩阵乘法
  8. 如何彻底卸载不需要的Mac屏保
  9. airplay协议开发第1部(搭建测试环境)
  10. 【Other】千字文 硬笔 楷书 字帖
  11. STM8S003 AWU休眠唤醒 寄存器和库函数2种做法
  12. JavaEE_Swagger
  13. 第一章 Java性能调优概述
  14. python图像识别植物识别_python 植物识别 error_code
  15. 华为telnet连接(无用户名登录和aaa模板登录)
  16. LM2596 负载增大,电压降低的问题
  17. rd,pe,ae,fae,marketing,sales都是干嘛的?
  18. rstudio 修改代码间距_R语言入门:使用RStudio的基本操作
  19. Muli3D 3 qQuaternionRotationMatrix 函数 (矩阵转四元数)
  20. Allegro174版本新功能介绍之和172版本兼容设置

热门文章

  1. 微信自动发卡小程序源码+带激励视频
  2. 瑞典条分法计算代码(恳请指正)
  3. mysql数据库链接驱动jar包的下载(Jmeter中使用为例)
  4. 【Unix/Linux】文件系统介绍 入门
  5. 成语验证码的引用(javaWeb)
  6. Spring MappingJackson2JsonView的使用
  7. QT 调用捷宇摄像头OCX控件,界面显示的控件非常小的问题。
  8. 重庆赛区 ▏2020年高教社杯全国大学生数学建模竞赛重庆赛区获奖名单
  9. Unity中内嵌网页插件 UniWebView,缩放网页
  10. 再论WGS84、ITRF2008及NavCom StarFire