接口的应用
1.就是说我们需要使用到一些数据,但是本自己没有这些数据,所有要调用第三方的数据提供方式,以接口的方式来获取数据
其实说白了,接口就是后台的public Controller
在php中的Think php 创建放置接口的文件夹Api
创建一个index.php
2.传送数据的方式Json 和 Xml
数据在php的控制器中互相转换
解析xml数据
将xml格式的数据转成php的对象
simpleXml_load_string( $xml 的字符串 ) ;
simpleXml_load_file( $xml 的路径 );
接口的请求 get post
我们可以通过file_get_contents()去发出请求,当我们在程序中需要访问第三方接口时,那么就要有一种请求的方式,在php中更多的使用curl函数实现,可以发送http https下的 get和psot方式请求.
要想使用curl函数,php本身需要开启curl拓展才能够使用curl函数库.配置php.ini文件开启,并且php的ext文件夹下有php_curl.dll文件
我们主要是通过cURL来完成,分为四部:
1.封装cURL的get请求:
//getf方式的请求function getRequest($url){
// var_dump($url);die;
$ch = curl_init();
//设置请求的路径
curl_setopt($ch,CURLOPT_URL,$url);
//不需要验证ssl证书
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,FALSE);
//设置获取的信息以文件流的形式返回,不在页面中输出任何结果
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$str = curl_exec($ch);
curl_close($ch);
return $str;
}
2.封装cURL的post请求:
function postRequest($url){
//初始话函数
$ch = curl_init();
//设置请求的路径
curl_setopt($ch, CURLOPT_URL, $url);
//不验证ssl证书
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false );
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false );
//设置请求的方式为post
curl_setopt($ch, CURLOPT_POST, 1 );
//设置请求时携带的参数
curl_setopt($ch, CURLOPT_POSTFIELDS, $data );
//设置请求结果以文件流的形式返回
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//发送请求
$str = curl_exec($ch);
//关闭请求
curl_close($ch);
return $str;
}
3.封装post和get请求(通用的):
//将post请求方式与get请求方式进行综合
function request($url,$https=false,$method="get",$data=null){
//1 初始化curl函数
$ch = curl_init($url);
//2 设置相关的参数
//以文件流的形式返回结果,不在页面输出任何结果
curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE);
//判断是否为https请求,如果是的话,就要验证ssl证书
if($https==true){
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);
}
//判断是否为post请求,如果是就传递参数
if($method=='post'){
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch,CURLOPT_POSTFIELDS,$data);
}
//发送请求
$str = curl_exec($ch);
// var_dump($str);
//关闭连接
curl_close($ch);
return $str;
}
测试get请求:
接口一: 获得国内手机号码归属地省份、地区和手机卡类型信息接口(360):
public function test4(){
$phone = '15101012345 ';
$url = "http://cx.shouji.360.cn/phonearea.php?number=".$phone;
//调用我们自定义的get请求,获取手机号码
$str = getRequest($url);
//将请求到的结果的json字符串转换为php数组
$arr = json_decode($str,true);
//将查询到的数据,进行整合处理
if($arr['code']==0){
echo '手机号码为:'.$phone.'<br/>';
echo '省份为:'.$arr['data']['province'].'<br/>';
echo '城市为:'.$arr['data']['city'].'<br/>';
echo '运营商:'.$arr['data']['sp'].'<br/>';
}
}
输出结果:
通过cURL的方法可以抓取访问的页面,保存到本地,CURLOPT_RETURNTRANSFER 设置为1时 , 把返回的结果赋值给变量,就是流 , 设置为 0 时,直接输出。
还需要注意,此处不需要验证证书:
cURL的发展迎来了更新 webService
webService介绍
这是一种夸编程语言和操作平台的专业的接口方式,不用考虑任何特定的传输协议(最常用的还是HTTP协议),可以允许任何类型的对象或代码,在任何平台上,以任何一直语言相互通信.在php中直接使用SoapClient类的相关方法请求即可.
soap协议的认识
SOAP(SimpleObjectaccessPRotocal,简单对象访问协议)技术有助于实现大量异构程序和平台之间的互操作性,从而使存在的应用能够被广泛的用户所访问。SOAP是把成熟的基于HTTP的WEB技术与xml的灵活性和可扩展性组合在了一起。
php对soap的支持
PHP5中的这个SOAP扩展目的是为了实现PHP对Web services的支持。与其它实现PHP对Web services的支持的方法不同,SOAP扩展是用C写的,因此它比其它方法具有速度优势. SoapClient 类就是可以基于SOAP协议访问webservice的php客户端。
使用webService
开启SOAP配置
重启apache
* 接口一: 获得国内手机号码归属地省份、地区和手机卡类型信息接口:*
方法一:
直接使用接口中的方法名进行调用,此时参数以一维数组的形式入参:
public function test2(){
//需要调用的webService接口
$wsl = "http://www.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl";
//实例话soapClient
$cli = new \SoapClient($wsl);
//调用号码查询的接口
//在这里直接调用的方法的名字,并且以一维数组形式传递参数
$str = $cli->getMobileCodeInfo(array(
'mobileCode'=> '15101012345',
'userID' => '',
));
print_r($str);
}
方法二:
__soapCall 方法用接口,此时是以二位数组形式入参:
public function test3(){
//需要调用的webService接口
$wsl = "http://www.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl";
//实例话soapClient
$cli = new \SoapClient($wsl);
//利用php的内置函数来调用接口
$str = $cli->__soapCall('getMobileCodeInfo', array(array(
'mobileCode'=>'15101012345',
'userID' =>''
)));
print_r($str);
}
输出结果:
打开soap配置后上述代码通过简单的使用web Service 来调用查询电话号码的接口
解释:
- SoapClient 是存在于 Soap.dll 扩展中的一个对象,用来“扮演” Soap 访问过程中的客户端,并为其提供相关功能。
- SoapClient 的实例化:它的构造函数包括两处参数,一个是 WSDL 文件(即 WSDL 地址),一个是选项列表,后面这个参数是可选的,它用来完成更复杂的访问,如使用代理访问,或者提供服务器需要验证的用户名和密码,等等。
- SoapClient 实例化之后,就可以通过该实例化对象来调用该 WebService提供的公有方法。
容联云通信短信接口
enter link description here
下载测试版本的demo
业务逻辑:
模板代码:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<style type="text/css" >
form{
margin:200px auto;
width:500px;
}
</style>
<body>
<form action="data.php" method="post">
<table>
<tr>
<td>手机号码:</td>
<td><input type="text" name="phone" id="phone" ><input type="button" id="btn" value="点击获取验证码"/></td>
</tr>
<tr>
<td>输入验证码:</td>
<td><input type="text"/></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="登录"/></td>
</tr>
</table>
</form>
</body>
</html>
<js href="__JQUERY__/jquery-1.6.2.min.js" />
<script>
var flage= false;
$('#btn').click(function(){
//获取手机号码
var phone = $('#phone').val();
//判断手机号是否合法
var reg = /^0?1[34568]\d{9}$/;
//如果手机号码为空,或者手机号码不合法
if(!reg.test(phone)){
alert('你输入的手机号码不正确!请核对后再输入!');
return false;
}
//为防止手机获取短信的行为被多次触发,需要加判断条件
if(flage){
alert('验证短信!已发送!请注意查收!失效期内不能重复的获取!');
return false;
}
//连接短信ajax
$.get("__CONTROLLER__/getRL/phone/"+phone,function(data){
var obj = $.parseJSON(data);
//如果返回的sign的0,表示短信发送成功!
if(obj.sign==0){
flage = true ;
//60秒之后重新获取
var time=60 ;
var _time = setInterval(function(){
if(time<1){
$('#btn').val('点击获取验证码').attr('disabled',false);
//清除记时器
clearInterval(_time);
}else{
$('#btn').val((time--)+'S秒后重新获取验证码!').attr('disabled',true);
}
},1000);
}else{
alert(obj.msg);
return false;
}
});
})
</script>
效果图:
已下是在TP框架中的应用
首先function.php中代码:
/**
* 发送模板短信
* @param to 手机号码集合,用英文逗号分开
* @param datas 内容数据 格式为数组 例如:array('Marry','Alon'),如不需替换请填 null
* @param $tempId 模板Id,测试应用和未上线应用使用测试模板请填写1,正式应用上线后填写已申请审核通过的模板ID
*/
function sendTemplateSMS($to,$datas,$tempId)
{
include_once("/Application/Api/Controller/CCPRestSmsSDK.php");
//主帐号,对应开官网发者主账号下的 ACCOUNT SID
$accountSid= '8aaf0708594f1f020159500506a800be';
//主帐号令牌,对应官网开发者主账号下的 AUTH TOKEN
$accountToken= 'd3fd7f8fcc41459385f3e7f9c49f696b';
//应用Id,在官网应用列表中点击应用,对应应用详情中的APP ID
//在开发调试的时候,可以使用官网自动为您分配的测试Demo的APP ID
$appId='8a216da8594f29f801595d54bff40323';
//请求地址
//沙盒环境(用于应用开发调试):sandboxapp.cloopen.com
//生产环境(用户应用上线使用):app.cloopen.com
$serverIP='sandboxapp.cloopen.com';
//请求端口,生产环境和沙盒环境一致
$serverPort='8883';
//REST版本号,在官网文档REST介绍中获得。
$softVersion='2013-12-26';
// 初始化REST SDK
//global $accountSid,$accountToken,$appId,$serverIP,$serverPort,$softVersion;
$rest = new \REST($serverIP,$serverPort,$softVersion);
$rest->setAccount($accountSid,$accountToken);
$rest->setAppId($appId);
// 发送模板短信
$result = $rest->sendTemplateSMS($to,$datas,$tempId);
//发送返回无结果
if($result == NULL ) {
$data=array(
'sign'=>1,
'code'=>"result error!",
'msg' =>'调用失败!',
);
return $data;
}
//发送返回结果是错误的
if($result->statusCode!=0) {
$data=array(
'sign'=>2,
'code'=>$result->statusCode,
'msg' =>$result->statusMsg,
);
return $data;
//TODO 添加错误处理逻辑
}else{
// 获取返回信息,结果发送成功
$smsmessage = $result->TemplateSMS;
$data = array(
'sign' => 0,
'code' => 'send success' .$smsmessage->dateCreated .$smsmessage->smsMessageSid,
'msg' => '短信发送成功!!!'
);
return $data;
//TODO 添加成功处理逻辑
}
}
IndexController.php中代码:
//容联云通信的短信验证接口的应用
public function duanxin(){
$this->display( 'duanxin' );
}
public function getRL($phone){
$phone = isset($phone)?htmlspecialchars($phone):'';
if($phone==''){
$this->get_data(3,'illegal params','请输入正确的手机号码!');
return false;
}
//满足条件调用
$key_60s = 'key_60s'.$phone;
$key_1d = 'key_1d'.$phone;
if(!$this->getStatusIn3600($key_60s) || !$this->getStatusIn86400($key_1d) ){
$this->get_data(4,'Dont again oneday','60s内不能重发一天之内只能验证3次!');
}
//随机获取随机数验证码
$num = rand(10000,99999);
//获取号码之后连接容联云通信
$result = sendTemplateSMS($phone,array($num,'5'),"1");//手机号码,替换内容数组,模板ID
echo json_encode($result);
}
/*
**设置一个数组用来拼接回复的json格式的信息
*/
private function get_data($sign , $code , $msg){
$data = array(
'sign' => $sign,
'code' => $code,
'msg' => $msg,
);
echo json_encode($data);die();
}
//写入数据,1天之内只能发送3条信息
private function getStatusIn86400($key_1d,$num=3){
$mem = new \Memcache();
$mem->connect('127.0.0.1',11211);
//先获取对应的key值的发送次数
$times = (int)$mem->get($key_1d);
if($times<$num){
$left_time = strtotime(date('Y-m-d 23:59:59'))-time(); //当天剩余的时间
$mem->set($key_1d,++$times,0,$left_time);
return true;
}else{
return false;
}
}
//增加60秒之内不能发送短信的限制
private function getStatusIn3600($key_60s,$time=60){
$mem = new \Memcache();
$mem->connect('127.0.0.1',11211);
$times = (int)$mem->get($key_60s);
if($times){
//存在值的话,说明60秒内有发送短信
return false;
}else{
$mem->set($key_60s,1,0,$time);
return true;
}
}