系统城装机大师 - 固镇县祥瑞电脑科技销售部宣传站!

当前位置:首页 > 网络编程 > PHP编程 > 详细页面

laravel框架使用阿里云短信发送消息操作示例

时间:2020-02-15来源:系统城作者:电脑系统城

本文实例讲述了laravel框架使用阿里云短信发送消息操作。分享给大家供大家参考,具体如下:

最新需要用到发送短信的功能,所以就在网上搜索一些写好的扩展。

扩展地址:

https://github.com/MissMyCat/aliyun-sms

通过composer安装:


 
  1. composer require mrgoon/aliyun-sms dev-master
  2.  

在 config/app.php 中 providers 加入:


 
  1. Mrgoon\AliSms\ServiceProvider::class,
  2.  

有需求的可以自行添加 aliases。

然后在控制台运行 :


 
  1. php artisan vendor:publish
  2.  

默认会在 config 目录下创建一个 aliyunsms.php 文件:


 
  1. <?php
  2. return [
  3. 'access_key' => env('ALIYUN_SMS_AK'), // accessKey
  4. 'access_secret' => env('ALIYUN_SMS_AS'), // accessSecret
  5. 'sign_name' => env('ALIYUN_SMS_SIGN_NAME'), // 签名
  6. ];
  7.  

然后在 .env 中配置相应参数:


 
  1. ALIYUN_SMS_AK=
  2. ALIYUN_SMS_AS=
  3. ALIYUN_SMS_SIGN_NAME=
  4.  

为了能够方便的发送短信,我们可以在 app 目录下,创建一个Services目录,并添加 AliyunSms.php 文件。


 
  1. <?php
  2. namespace App\Services;
  3. use Mrgoon\AliSms\AliSms;
  4. /**
  5. * 阿里云短信类
  6. */
  7. class AliyunSms
  8. {
  9. //验证码
  10. const VERIFICATION_CODE = 'verification_code';
  11. //模板CODE
  12. public static $templateCodes = [
  13. self::VERIFICATION_CODE => 'SMS_XXXXXXXXXX',
  14. ];
  15. /**
  16. * 发送短信
  17. */
  18. public static function sendSms($mobile, $scene, $params = [])
  19. {
  20. if (empty($mobile)) {
  21. throw new \Exception('手机号不能为空');
  22. }
  23. if (empty($scene)) {
  24. throw new \Exception('场景不能为空');
  25. }
  26. if (!isset(self::$templateCodes[$scene])) {
  27. throw new \Exception('请配置场景的模板CODE');
  28. }
  29. $template_code = self::$templateCodes[$scene];
  30. try {
  31. $ali_sms = new AliSms();
  32. $response = $ali_sms->sendSms($mobile, $template_code, $params);
  33. if ($response->Code == 'OK') {
  34. return true;
  35. }
  36. throw new \Exception($response->Message);
  37. } catch (\Throwable $e) {
  38. throw new \Exception($e->getMessage());
  39. }
  40. }
  41. }
  42.  

为了能够记录每次短信发送的状态,我们可以创建一个 sms_logs 表。


 
  1. CREATE TABLE `sms_logs` (
  2. `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
  3. `type` tinyint(1) NOT NULL DEFAULT '0' COMMENT '类型(0:短信验证码,1:语音验证码,2:短信消息通知)',
  4. `mobile` varchar(16) NOT NULL DEFAULT '' COMMENT '手机号',
  5. `code` varchar(12) NOT NULL DEFAULT '' COMMENT '验证码',
  6. `checked` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否验证(0:未验证,1:已验证)',
  7. `status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '状态(0:未发送,1:已发送,2:发送失败)',
  8. `reason` varchar(255) NOT NULL DEFAULT '' COMMENT '失败原因',
  9. `remark` varchar(255) NOT NULL DEFAULT '' COMMENT '备注',
  10. `operator_id` int(11) NOT NULL DEFAULT '0' COMMENT '操作人ID',
  11. `ip` varchar(16) NOT NULL DEFAULT '' COMMENT '操作IP',
  12. `created` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
  13. `updated` int(11) NOT NULL DEFAULT '0' COMMENT '更新时间',
  14. PRIMARY KEY (`id`)
  15. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='短信表';
  16.  

然后针对该表,我们创建一个 SmsLog 模型来管理。


 
  1. <?php
  2. namespace App\Models;
  3. use App\Services\AliyunSms;
  4. class SmsLog extends Model
  5. {
  6. protected $fillable = [
  7. 'type',
  8. 'mobile',
  9. 'code',
  10. 'checked',
  11. 'status',
  12. 'reason',
  13. 'remark',
  14. 'operator_id',
  15. 'ip',
  16. ];
  17. //类型(0:短信验证码,1:语音验证码,2:短信消息通知)
  18. const TYPE_CODE = 0;
  19. const TYPE_VOICE = 1;
  20. const TYPE_MESSAGE = 2;
  21. //是否验证(0:未验证,1:已验证)
  22. const CHECKED_UNVERIFIED = 0;
  23. const CHECKED_VERIFIED = 1;
  24. //状态(0:未发送,1:已发送,2:发送失败)
  25. const STATUS_NO_SEND = 0;
  26. const STATUS_SEND = 1;
  27. const STATUS_FAIL = 2;
  28. //短信发送间隔时间,默认60秒
  29. const SEND_INTERVAL_TIME = 60;
  30. /**
  31. * 检测短信验证码
  32. */
  33. protected function checkCode($mobile, $code)
  34. {
  35. if (!$mobile) {
  36. throw new \Exception('手机号不能为空');
  37. }
  38. if (!checkMobile($mobile)) {
  39. throw new \Exception('手机号不正确');
  40. }
  41. if (!$code) {
  42. throw new \Exception('验证码不能为空');
  43. }
  44. $sms_log = $this->where([
  45. ['type', self::TYPE_CODE],
  46. ['mobile', $mobile],
  47. ['status', self::STATUS_SEND],
  48. ['checked', self::CHECKED_UNVERIFIED],
  49. ])->orderBy('created', 'desc')->first();
  50. if (!$sms_log) {
  51. throw new \Exception('验证码不存在,请重新获取');
  52. }
  53. if ($code != $sms_log->code) {
  54. throw new \Exception('验证码错误');
  55. }
  56. $sms_log->checked = self::CHECKED_VERIFIED;
  57. $sms_log->save();
  58. return true;
  59. }
  60. /**
  61. * 检测短信频率
  62. */
  63. protected function checkRate($mobile)
  64. {
  65. if (!$mobile) {
  66. throw new \Exception('手机号不能为空');
  67. }
  68. $sms_log = $this->where([
  69. ['mobile', $mobile],
  70. ['status', self::STATUS_SEND],
  71. ])->orderBy('created', 'desc')->first();
  72. $now = time();
  73. if ($sms_log) {
  74. if (($now - strtotime($sms_log->created)) < self::SEND_INTERVAL_TIME) {
  75. throw new \Exception('短信发送太频繁,请稍后再试');
  76. }
  77. }
  78. return true;
  79. }
  80. /**
  81. * 发送短信验证码
  82. */
  83. protected function sendVerifyCode($mobile)
  84. {
  85. self::checkRate($mobile);
  86. $code = mt_rand(1000, 9999);
  87. $sms_log = $this->create([
  88. 'type' => self::TYPE_CODE,
  89. 'mobile' => $mobile,
  90. 'code' => $code,
  91. 'checked' => self::CHECKED_UNVERIFIED,
  92. 'status' => self::STATUS_NO_SEND,
  93. 'ip' => getRealIp(),
  94. ]);
  95. try {
  96. AliyunSms::sendSms($mobile, AliyunSms::VERIFICATION_CODE, ['code' => $code]);
  97. $sms_log->status = self::STATUS_SEND;
  98. $sms_log->save();
  99. return true;
  100. } catch (\Exception $e) {
  101. $sms_log->status = self::STATUS_FAIL;
  102. $sms_log->reason = $e->getMessage();
  103. $sms_log->save();
  104. throw new \Exception($e->getMessage());
  105. }
  106. }
  107. }
  108.  

这样,我们就可以在项目中通过 SmsLog::sendVerifyCode() 发送短信了。

getRealIp() 和 checkMobile() 方法为公共方法,存放在 app/Helpers 的 functions.php 中。


 
  1. /**
  2. * 获取真实IP地址
  3. */
  4. function getRealIp()
  5. {
  6. $ip = false;
  7. if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown")) {
  8. $ip = getenv("HTTP_CLIENT_IP");
  9. } else if (getenv("HTTP_X_FORWARDED_FOR") &&strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown")) {
  10. $ips = explode(", ", getenv("HTTP_X_FORWARDED_FOR"));
  11. if ($ip) {
  12. array_unshift($ips, $ip);
  13. $ip = false;
  14. }
  15. $ipscount = count($ips);
  16. for ($i = 0; $i < $ipscount; $i++) {
  17. if (!preg_match("/^(10|172\.16|192\.168)\./i", $ips[$i])) {
  18. $ip = $ips[$i];
  19. break;
  20. }
  21. }
  22. } else if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown")) {
  23. $ip = getenv("REMOTE_ADDR");
  24. } else if (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] &&strcasecmp($_SERVER['REMOTE_ADDR'], "unknown")) {
  25. $ip = $_SERVER['REMOTE_ADDR'];
  26. } else {
  27. $ip = "unknown";
  28. }
  29. return isIp($ip) ? $ip : "unknown";
  30. }
  31. /**
  32. * 检查是否是合法的IP
  33. */
  34. function isIp($ip)
  35. {
  36. if (preg_match('/^((\d|[1-9]\d|2[0-4]\d|25[0-5]|1\d\d)(?:\.(\d|[1-9]\d|2[0-4]\d|25[0-5]|1\d\d)){3})$/', $ip)) {
  37. return true;
  38. } else {
  39. return false;
  40. }
  41. }
  42. /**
  43. * 验证手机号
  44. */
  45. function checkMobile($mobile)
  46. {
  47. return preg_match('/^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\d{8}$/i', $mobile);
  48. }
  49.  

更多关于Laravel相关内容感兴趣的读者可查看本站专题:《Laravel框架入门与进阶教程》、《php优秀开发框架总结》、《php面向对象程序设计入门教程》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》

希望本文所述对大家基于Laravel框架的PHP程序设计有所帮助。

分享到:

相关信息

  • Thinkphp框架+Layui实现图片/文件上传功能分析

    这篇文章主要介绍了Thinkphp框架+Layui实现图片/文件上传功能,结合实例形式详细分析了Thinkphp+Layui实现图片文件上传的具体步骤、原理与相关操作技巧...

    2020-02-07

  • Laravel框架自定义分页样式操作示例

    这篇文章主要介绍了Laravel框架自定义分页样式操作,结合实例形式详细分析了laravel框架自定义分页样式的具体操作步骤、实现方法及相关注意事项,需要的朋友可以参考下...

    2020-02-03

系统教程栏目

栏目热门教程

人气教程排行

站长推荐

热门系统下载