使用PHP通过移动云MAS发送短信

背景

客户端发送一个请求到服务器,将信息通过短信告知用户。这个是很常见的一种消息推送的方式。这次也需要完成这样的功能。
我们选择的移动短信平台为10086的云MAS的平台,接口选择最简单的HTTP接口。

方案

短信平台 数据接口 服务端 客户端
中国移动云MAS 云MAS提供的HTTP接口 PHP开发的服务 Html+JS

必要的非技术准备

  1. 需要一个中国移动云MAS业务平台的集团账号。通常应该是业主方购买,如果乙方购买,自行脑补运维费怎么弄。
  2. PHP开发通用的POST请求程序与云MAS对接。

实战

步骤 Subject 备忘 说明
1 获得云MAS接口账号 移动集团账号登录http://mas.10086.cn/login开通 详细手册在网站有下载
2 下载配套的签名秘钥 根据移动手册step by step操作即可,下载的是一个excel文件中包含 -
3 使用PHP curl功能 制作配套的POST函数,将短信发送出去 -
4 完成响应客户端请求的php脚本 - -

封装一个Mas Class

  • 附送一个代码段,不同的需求可以不同的改造。
  • 这里使用了读取ini获得配置,这样不修改程序的情况下,修改ini即可完成数据功能切换。
  • 优化余地:对应短信发送之后的response处理可以根据手册更加丰富的处理。
<?php
/**
 * ==================================================================
 * created by YYXOCHEN on 2018.09.27
 * Copyright (c) 2017-2027 YYXOCHEN  All Rights Reserved
 * ==================================================================
 * 适配移动云MAS系统的http请求发送普通短信功能的类
 * 需要配置http请求的接口的相关账号,数据可以维护到config/config.ini中
 * ------------------------------------------------------------------
 * 接口参数说明:
 * @param string $ecName
 * @param string $apId
 * @param string $mobiles 逗号分隔手机号码
 * @param string $content
 * @param string $sign 下载的签名中有
 * @param string $addSerial 扩展码,根据向移动公司申请的通道填写,如果申请的精确匹配通道,则填写空字符串(""),否则添加移动公司允许的扩展码
 * @param string $mac API输入参数签名结果,签名算法:将ecName,apId,secretKey,mobiles,content ,sign,addSerial按照顺序拼接,然后通过md5(32位小写)计算后得出的值
 * 以上数据需要字符集utf8
 * POST请求路径:http://112.35.1.155:1992/sms/norsubmit
 * ------------------------------------------------------------------
 * 使用范例:
 * require_once "util/mas.10086.class.php";
 * $mas = new Mas10086();
 * $response = $mas->sendSms('138 XXXX XXXX', 'Hello World!');
 * var_dump($response);
 * ------------------------------------------------------------------
 * version 1.0
 * 可以通过http接口,发送sms普通短信,接口适配mas的 HTTP2.1 版本
 */

class Mas10086
{
    /**
     * 项目常量配置,如果有config则可以不用,这里作为默认值配置
     * 更为通用的方式,应该是用config.ini中配置[MAS_10086]
     */
    const AP_ID   = 'XXXX';
    const SIGN    = 'XXXX';
    const ADD_SERIAL = '';
    const SECRET_KEY  = 'XXXX';
    const EC_NAME = 'XXXX';
    const NORMAL_SMS_URL = 'http://112.35.1.155:1992/sms/norsubmit';

    const MAS_VERSION = '2.1';

    private $apId = '';
    private $sign = '';
    private $addSerial = '';
    private $secretKey = '';
    private $ecName = '';
    private $norSmsUrl = '';

    /**
     * 初始化操作:读取config,设定配置参数
     * 如果没有配置,则使用默认
     */
    function __construct()
    {
        $ini = parse_ini_file("../../Config/config.ini",true);

        $masKey = 'MAS_10086_'.self::MAS_VERSION;

        if (!isset($ini[$masKey])) {
            $this->apId      = self::AP_ID;
            $this->sign      = self::SIGN;
            $this->addSerial = self::ADD_SERIAL;
            $this->secretKey = self::SECRET_KEY;
            $this->ecName    = self::EC_NAME;
            $this->norSmsUrl = self::NORMAL_SMS_URL;
        } else {            
            $this->apId       = isset( $ini[$masKey]['AP_ID'])          ? $ini[$masKey]['AP_ID']          : self::AP_ID;
            $this->sign       = isset( $ini[$masKey]['SIGN'])           ? $ini[$masKey]['SIGN']           : self::SIGN;
            $this->addSerial  = isset( $ini[$masKey]['ADD_SERIAL'])     ? $ini[$masKey]['ADD_SERIAL']     : self::ADD_SERIAL;
            $this->secretKey  = isset( $ini[$masKey]['SECRET_KEY'])     ? $ini[$masKey]['SECRET_KEY']     : self::SECRET_KEY;
            $this->ecName     = isset( $ini[$masKey]['EC_NAME'])        ? $ini[$masKey]['EC_NAME']        : self::EC_NAME;
            $this->norSmsUrl  = isset( $ini[$masKey]['NORMAL_SMS_URL']) ? $ini[$masKey]['NORMAL_SMS_URL'] : self::NORMAL_SMS_URL;
            xlog('I','read mas10086 config from ini file');
        }
    }

    /**
     * 根据MAS的接口规范,需要装配一组mac字符串做验证
     * @param string $mobiles 逗号分隔得电话号码字符串
     * @param string $content
     * @return string
     */
    private function makeMacString($mobiles,$content)
    {
        $macstr = $this->ecName . $this->apId . $this->secretKey . $mobiles . $content . $this->sign . $this->addSerial;
        return strtolower( md5($macstr) );
    }

    /**
     * 内置一个curl定制的发送请求的函数,专门配置
     * @param string $data 发送的数据
     * @return string 请求结果信息
     */
    private function post($url, $data)
    {
        if (!$url) {
            return false;
        }

        $curl = curl_init();
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_TIMEOUT, 500);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);

        $res = curl_exec($curl);
        curl_close($curl);
        return $res;
    }

    /**
     * sendSms
     * 发送短信函数
     * @param array $phoneNumberList 电话号码数组
     * @param string $content 短信文本
     * @return object Mas10086的标准接口     *  
     *  @param string $rspcod, 响应码(根据下面返回值判断)
     *  @param string $msgGroup, 消息批次号,由云MAS平台生成,用于验证短信提交报告和状态报告的一致性(取值msgGroup)注:如果数据验证不通过msgGroup为空
     *  @param boolean $success
     */
    public function sendSms($phoneList, $content='来自AsieMatrix的信息')
    {
        if (is_array($phoneList)) {
            if (count($phoneList) == 0) {
                return false;
            } 
            $mobiles = implode(',', $phoneList);
        } else {
            $mobiles = $phoneList;
        }
        
        $content .= "\n\r".'[系统短信,请勿回复]';

        $mobiles = ltrim(rtrim($mobiles, ','),',');

        $macstr = $this->makeMacString($mobiles,$content);

        $data = [
            'addSerial' => $this->addSerial,
            'apId' => $this->apId,
            'content' => $content,
            'ecName' => $this->ecName,
            'mobiles' => $mobiles,
            'sign'=>$this->sign,
            'mac' => $macstr
        ];
        
        $dataContent = base64_encode( json_encode($data) );

        $res = json_decode($this->post($this->norSmsUrl, $dataContent));
        return $res;
    }
}

?>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,898评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,401评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,058评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,539评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,382评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,319评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,706评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,370评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,664评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,715评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,476评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,326评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,730评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,003评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,275评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,683评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,877评论 2 335

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,132评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,510评论 18 139
  • 点击查看原文 Web SDK 开发手册 SDK 概述 网易云信 SDK 为 Web 应用提供一个完善的 IM 系统...
    layjoy阅读 13,597评论 0 15
  • 魏世杰,魏老,1941年生人,如今76岁了,个子不高,胖胖的,甚至还有点憨厚,但却是地地道道的山东汉子。 年轻时在...
    山知阅读 301评论 0 0
  • 慢一点 再慢一点 走路慢一点 吃饭慢一点 老的慢一点 说话慢一点 声音柔一点 做事认真点 学学蜗牛 学学乌龟 慢吞...
    祥云如梦阅读 294评论 2 4