php 生成不同的短信验证码_「PHP开发APP接口实战012」发送短信验证码之生成并缓存验证码(Memcache)...

配置参数Memcache 配置, 在 /app/config/config.ini 文件添加以下代码:[memcache]

host = 127.0.0.1

port = 11211

prefix = api在 Visual NMP 中,默认已经安装了 Memcache, 可直接使用。如服务未开启,直接打开即可。 默认连接端口:11211。缓存键名前缀:prefix = api,方便区分项目,可随意设置, 一般设置为项目名。

「PHP开发APP接口实战001」开发环境搭建短信配置, 在 /app/config/config.php 文件添加以下代码:'sms' => [        'times' => 3, // 同一手机一小时内发送短信次数, 0 为不限制

'interval' => 60, // 同一手机两次发送间隔时间(单位:秒), 0 为不限制

'valid_time' => 300, // 短信验证码有效时间(单位:秒), 0 为久有效

],

创建 Memcache 操作类 XMemcache

在 /app/library 目录下创建文件 XMemcache.php, 添加以下代码:<?php /**

* 缓存

*/class XMemcache{    public static $instance;    private $memcache = null; // Memcache 对象

private $config = null; // 配置参数

private $tag = null; // 标识

private function __construct($tag = null)

{        // 初始化 Memcache 对象

$this->memcache = new Memcache();        // 加载配置参数

$this->config = Config::instance()->get('memcache', 'ini');        // 连接Memcache服务器

$this->memcache->addServer($this->config['host'], $this->config['port']);        $this->tag = $tag;

}    /**

* @param null $tag  缓存标识

* @return XMemcache

*/

public static function instance($tag = null)

{        if (!self::$instance) self::$instance = new self($tag);        return self::$instance;

}    /**

* 添加缓存,若不存在则追加,若不存在则新增

* @param $key 键名

* @param $value 缓存内容

* @param int $timeout 0永久有效,604800 7天,最大不能超过30天

* @param int $iszip

* @return mixed

*/

public function append($key, $value, $timeout = 604800, $iszip = 0)

{        if ($values = $this->get($key)) {

$values[] = $value;

} else {

$values = [$value];

}        $this->set($key, $values, $timeout, $iszip);

}    /**

* 设置缓存

* @param $key 键名

* @param $value 缓存内容

* @param int $timeout 0永久有效,604800 7天,最大不能超过30天

* @param int $iszip

* @return mixed

*/

public function set($key, $value, $timeout = 604800, $iszip = 0)

{

$value = serialize($value);        return $this->memcache->set($this->formatKey($key), $value, $iszip, $timeout);

}    /**

* 根据KEY获得缓存内容

* @param $key

* @return mixed

*/

public function get($key)

{

$value = $this->memcache->get($this->formatKey($key));        return unserialize($value);

}    /**

* 删除指定缓存

* @param $key

* @return mixed

*/

public function delete($key)

{        return $this->memcache->delete($this->formatKey($key));

}    /**

* 清空缓存

* @return mixed

*/

public function flush()

{        return $this->memcache->flush();

}    /**

* 重写缓存键名,格式: [prefix]:[tag]:[key]

* @param $key

* @return string

*/

private function formatKey($key)

{        return $this->config['prefix'] . ':' . $this->tag . ':' . $key;

}

}这里重写了一些 Memcache 常用的操作函数。 如:设置缓存 set(),  追加缓存 append(),  获取缓存 get(), 删除缓存 delete(), 清空缓存 flush()

值得注意的是,我们还对缓存键名进行了重写,方便区分项目和模块。

生成短信验证码在 /app/library 目录下创建文件 SMS.php, 添加以下代码:<?php /**

* 短信验证码

*/class SMS{    public static $instance;    // 配置参数

private $config = null;    private function __construct()

{        // 加载短信配置参数

$this->config = Config::instance()->get('sms');

}    public static function instance()

{        if (!self::$instance) self::$instance = new self();        return self::$instance;

}

}这里实现了实例化时,自己加载配置参数。增加验证码改送函数 send(), 用于外部调用。如:/**

* 发送短信验证码

* @param $mobile

* @return array

* @throws Exception

*/

public function send($mobile)

{

}此函数里面分四步走:验证指定手机号,当前是否可以发送验证码

生成四位数字验证码,并配置上生成时间

调用 XMemcache 缓存验证码

调用第三方接口,发送验证码,并返回发送状态。(市场上有许多发送第三方平台,都有)这里调换一下顺序,先讲解生成和缓存验证码。

首先,添加函数generateCode(), 随机生成4位数字验证码/**

* 随机生成4位数字验证码

* @return int

*/

private function generateCode()

{        return rand(1000, 9999);

}

然后,在 send() 函数中添加代码:$item = [            'code' => $this->generateCode(), // 生成短信验证码

'time' => time(), // 生成时间

'verified' => 0,  // 验证状态: 0 未验证, 1 已验证

];这里除了生成验证码,同时初始化生成时间time, 验证状态verified,用于验证发送时间和检查验证码是否已验证。缓存验证码,在 send() 函数中添加代码:// 缓存短信验证码

XMemcache::instance('sms')->append($mobile, $item, 3600);这里完成了几个工作:将 $item 存于以指定手机号为键名的缓存下

同一手机号多次发送,都存在同一键名下,用于统计1小时内验证码发送次数。

缓存有效时间设置为 1 小时现在我们再回来讲解验证是否允许向指定手机号发送验证码。验证规则:同一手机两次发送间隔时间1分钟(可配置间隔时间)

同一手机1小时内最多只能发送3次验证码(可配置发送次数)

首先,添加函数 getCacheCodes() 和 validateSend(), 如:/**

* 获取1小时内发送的验证码

* @param $mobile

* @return null

*/

private function getCacheCodes($mobile)

{

$codes = XMemcache::instance('sms')->get($mobile);        if (!$codes)            return [];        foreach ($codes as $index => $item) {            // 过滤发送超过1小时的验证码

if (time() - $item['time'] > 3600) {                unset($codes[$index]);

}

}        // 重置数组索引

$codes = array_values($codes);        // 更新缓存

XMemcache::instance('sms')->set($mobile, $codes);        return $codes;

}    /**

* 验证是不否允许发送

* @param $mobile

* @throws Exception

*/

private function validateSend($mobile)

{

$codes = $this->getCacheCodes($mobile);        if ($this->config['times'] > 0 && count($codes) >= $this->config['times']) {            throw new Exception('一小时内最多只能发送' . $this->config['times'] . '次短信验证码');

}

$lastCode = end($codes);        if ($this->config['interval'] > 0 && time() - $lastCode['time'] <= $this->config['interval']) {            throw new Exception('发送频率太快');

}

}函数 getCacheCodes() 获取指定手机1小时内发送的验证码。

函数 validateSend() 实现:

验证一小时内向同一手机发送短信验证码次数是否超过了配置次数;

验证上次发送验证码是否已经超过配置时间;

然后在 send() 函数中,所有代码之前插入代码 $this->validateSend($mobile);。

send() 函数完整代码:/**

* 发送短信验证码

* @param $mobile

* @return array

* @throws Exception

*/

public function send($mobile)

{        // 验证短信发送次数

$this->validateSend($mobile);

$item = [            'code' => $this->generateCode(), // 生成短信验证码

'time' => time(), // 生成时间

'verified' => 0,  // 验证状态: 0 未验证, 1 已验证

];        // 缓存短信验证码

XMemcache::instance('sms')->append($mobile, $item, 3600);        // 发送短信验证码

/* ... 调用第三方接口 ... */

return $item;

}再在控制器 SmsController 类的 sendAction() 函数中加入以下代码:// 发送验证码

$result = SMS::instance()->send($this->getPost('user_mobile'));        if ($result) {//            Output::instance($this->response)->success(’发送成功‘);

Output::instance($this->response)->success((object)$result);

} else {

Output::instance($this->response)->fail('发送失败');

}这里没有真正实现调用第三方接口,而是直接返回了发送的验证码,以供测试使用。正式代码,只返回发送状态。

SmsController.php 完整代码:<?phpclass  SmsController extends BaseController{    /**

* 发送短验证码

*/

public function sendAction()

{        // 验证请求方法是否是POST

$this->isPost();        // 验证请求参数

XValidationSms::send($this->getPost());        // 发送验证码

$result = SMS::instance()->send($this->getPost('user_mobile'));        if ($result) {//            Output::instance($this->response)->success(’发送成功‘);

Output::instance($this->response)->success((object)$result);

} else {

Output::instance($this->response)->fail('发送失败');

}

}

}

接口调试示例请求方式:POST

请求参数:user_mobile=18088888888

返回数据:{    "status": "1",    "value": "发送成功"}

开发调试时返回数据 :{    "status": "1",    "item": {        "code": "1139",        "time": "1520663958",        "verified": "0"

}

}

AAffA0nNPuCLAAAAAElFTkSuQmCC

作者:一念觀心

链接:https://www.jianshu.com/p/0dbdf556b4f3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值