laravel接入短信api

本文介绍了一个短信验证码接口的设计过程,包括路由配置、控制器创建、数据库模型建立及短信发送逻辑实现等步骤。

短信接口服务运营商以互亿无线为例
1.定义路由
首先定义api路由:routes/api.php

Route::post('sms','SmsController@sms');

Route::post(‘send_sms’,‘SmsController@send_sms’);

2.设置路由
位置:app/Providers/RouteServiceProvider.php

// 项目的路由地址

protected $customNamespace = ‘App\Http\Api’;

protected function mapApiRoutes()
{
Route::prefix(‘api’)
->middleware(‘api’)
->namespace($this->customNamespace)
->group(base_path(‘routes/api.php’));
}

3.创建api文件(创建到app\http\api目录下)
命令:php artisan make:controller App\Http\Api\SmsController

4.创建数据库模型Model
命令:php artisan make:model Model\Sms -m(同时创建Model和对应数据表迁移文件)

<?php

namespace App\Model;

//use Illuminate\Database\Eloquent\Model as SmsModel;

class Sms extends Model
{
    protected $table        = 'sms';
    protected $fillable = ['sms_phone','ver_code','sms_time','sms_count'];
}

$table 模型关联数据表
$fillable 指定字段白名单,只有这个里面的字段才允许操作
}
}

database/migrations/2018_09_11_180044_create_sms_models_table.php内容:

   <?php
    
    use Illuminate\Support\Facades\Schema;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Database\Migrations\Migration;
    
    class CreateSmsModelsTable extends Migration
    {
        /**
         * Run the migrations.
         *
         * @return void
         */
        public function up()
        {
            Schema::create('sms_models', function (Blueprint $table) {
                $table->uuid('id')->primary();
                $table->string('tel',11)->comment('电话号码');
                $table->string('code')->comment('验证码');
                $table->integer('num')->comment('次数');
                $table->string('timesms')->comment('时间');
                $table->timestamps();
            });
        }
    
        /**
         * Reverse the migrations.
         *
         * @return void
         */
        public function down()
        {
            Schema::dropIfExists('sms_models');
        }
    }

在SmsController里面实现逻辑(此接口主要逻辑:接收参数电话号码,按照运营商提供的规则,生成发送短信请求,将电话号码和验证码存入redis里面,设置过期时间:如60s,避免同一个号码反复发送),例如:

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/9/11 0011
 * Time: 11:18
 */

namespace App\Http\Api;

use App\Model\TestModel;
use Illuminate\Support\Facades\Redis;
use App\Model\Sms;
//开启SESSION
$GLOBALS['ihuyi']['appid']					= 'C66713053';
$GLOBALS['ihuyi']['appkey']					= '699bfa3db9fbeddda629b1c78b04f890';
$GLOBALS['ihuyi']['sms_send_time']			= 60;
$GLOBALS['ihuyi']['sms_send_num']			= 5;
$GLOBALS['ihuyi']['sms_send_black_time']	= 600;
$GLOBALS['ihuyi']['url']					= "http://106.ihuyi.cn/webservice/sms.php?method=Submit";
$GLOBALS['ihuyi']['is_open_send_limit']		= 1;
class TestController extends  Controller
{
public function __construct(){
        header("Content-type:text/html; charset=UTF-8");

    }

    //请求数据到短信接口,检查环境是否 开启 curl init。
    private function post($curlPost,$url){
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HEADER, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_NOBODY, true);
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $curlPost);
        $return_str = curl_exec($curl);
        curl_close($curl);
        return $return_str;
    }

    //将 xml数据转换为数组格式。
    private function xml_to_array($xml){
        $reg = "/<(\w+)[^>]*>([\\x00-\\xFF]*)<\\/\\1>/";
        if(preg_match_all($reg, $xml, $matches)){
            $count = count($matches[0]);
            for($i = 0; $i < $count; $i++){
                $subxml= $matches[2][$i];
                $key = $matches[1][$i];
                if(preg_match( $reg, $subxml )){
                    $arr[$key] = $this-> xml_to_array( $subxml );
                }else{
                    $arr[$key] = $subxml;
                }
            }
        }
        return $arr;
    }

    //random() 函数返回随机整数。
    private function random($length = 6 , $numeric = 0) {
        PHP_VERSION < '4.2.0' && mt_srand((double)microtime() * 1000000);
        if($numeric) {
            $hash = sprintf('%0'.$length.'d', mt_rand(0, pow(10, $length) - 1));
        } else {
            $hash = '';
            $chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789abcdefghjkmnpqrstuvwxyz';
            $max = strlen($chars) - 1;
            for($i = 0; $i < $length; $i++) {
                $hash .= $chars[mt_rand(0, $max)];
            }
        }
        return $hash;
    }

    //防止恶意攻击
    /*private function sms_safe(){
        if($GLOBALS['ihuyi']['is_open_send_limit']!=1){
            return;
        }
        if (!empty($_SESSION['sms_send_black']) && $_SESSION['sms_send_black'] + $GLOBALS['ihuyi']['sms_send_black_time'] > time()) {
            exit('操作频繁,请'.ceil(($_SESSION['sms_send_black'] + $GLOBALS['ihuyi']['sms_send_black_time'] - time())/60).'分钟后重试');
        }

        if (empty($_SESSION['sms_send_num'])) {
            $_SESSION['sms_send_num'] = 1;
        }

        if(!empty($_SESSION['sms_send_time']) && $_SESSION['sms_send_time'] + $GLOBALS['ihuyi']['sms_send_time'] > time()){
            exit('操作频繁,请'.($_SESSION['sms_send_time'] + $GLOBALS['ihuyi']['sms_send_time'] - time()).'秒后重试');
        }

        if ($_SESSION['sms_send_num'] > $GLOBALS['ihuyi']['sms_send_num']) {
            $_SESSION['sms_send_black'] = time();
            unset($_SESSION['sms_send_num']);
            unset($_SESSION['sms_send_time']);
            exit('发送次数超过限制');
        }
    }*/

    //发送短信验证码
    public function send_sms(Request $request){
        //获取手机号
        $mobile=$request->input('mobile');
            if(Redis::exists($mobile)){//判断电话号码是否存在
            $data['code']='200';
            $data['success']='false';
            $data['msg']='请60s后请求接口';
            $data['data']=null;
            return $data;
            }
        Redis::setex($mobile,60,'1');//设置过期时间60s过期

        // 短信接口地址
        $target = $GLOBALS['ihuyi']['url'];

        //生成的随机数
        $mobile_code = $this->random(6,1);
        if(empty($mobile)){
            exit('手机号码不能为空');
        }

        $preg = "/^1[3456789]\d{9}$/";
        if (!preg_match($preg, $mobile)) {
            exit('手机号码不正确');
        }

        //防止恶意攻击 session 部分代码最好通过redis代替session实现
        // $this->sms_safe();
        $content = "您的验证码是:".$mobile_code."。请不要把验证码泄露给其他人。" ;
        $post_data = "account=".$GLOBALS['ihuyi']['appid'] ."&password=".$GLOBALS['ihuyi']['appkey'] ."&mobile=".$mobile."&content=".rawurlencode($content);
        $sms_phone = Sms::where('sms_phone',$mobile)->get()->toArray();
        $gets = $this-> xml_to_array($this->post($post_data, $target));
        if($gets['SubmitResult']['code']==2) {
            if (empty($sms_phone)) {
                Sms::create([
                    'sms_phone' => $mobile,
                    'ver_code' => $mobile_code,
                    'sms_time' => time(),
                    'sms_count' => 1,
                ]);
            } else {
                Sms::where('sms_phone', $mobile)->update([
                    'ver_code' => $mobile_code,
                    'sms_time' => time()
                ]);
                Sms::increment('sms_count', 1);
            }
        }
        $data=array([
            'code'=>$gets['SubmitResult']['code'],
            'msg'=>$gets['SubmitResult']['msg'],
            'data'=>null,
            ]);


       return $data;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值