來展示:
1、首先你得裝阿里簡訊sdk
composer require alibabacloud/sdk
發簡訊控制器
<?php
namespace App\Controllers;
use App\Requests\App\AppSendSmsRequest;
use App\Services\SmsService as Service;
use Framework\BaseController;
use Framework\Hope;
use Mews\Captcha\Facades\Captcha;
class SmsController extends BaseController
{
/**
* @var Service
*/
private $service;
public function __construct(Service $service)
{
$this->service = $service;
}
/** 提交圖形驗證碼
* @param AppSendSmsRequest $request
*/
public function send_sms(AppSendSmsRequest $request)
{
$phone = $request->phone();
$key = $request->key();
$code = $request->code();
$flg = captcha_api_check($code, $key);
if (!$flg && (!Hope::isProduct() && $code != 'ASDF')) {
$this->retError('圖形驗證碼錯誤');
}
if(!Hope::isProduct()){
$code = substr($phone, -4);
$redis = Hope::getRedis();
$redis->setex("sms:" . $phone, 60 * 5, $code);
}else{
//獲取簡訊驗證碼
$this->getVerifyCode($phone);
}
$this->retSuccess(true);
}
/**
* 獲取圖形驗證碼
*/
public function get_sms()
{
$res = Captcha::create('default', true);
$this->retSuccess($res);
}
/**
* 獲取簡訊驗證碼
*/
public function getVerifyCode($phone)
{
$this->service->sendSmsVerifyCode($phone);
}
}
服務層
<?php
namespace App\Services;
use App\Services\Sms\HttpService;
use Carbon\Carbon;
use Framework\BaseService;
use Framework\Hope;
class SmsService extends BaseService
{
/** 傳送簡訊驗證碼
* @param string $phone
* @return bool
* @throws \AlibabaCloud\Client\Exception\ClientException
*/
public function sendSmsVerifyCode(string $phone)
{
if(!Hope::isProduct()){
return true;
}
$redis = Hope::getRedis();
$key = $this->getKey($phone);
$limitKey = 'code_limit';
// 驗證碼重發限制
$jsonData = $redis->get($key);
$data = $jsonData ? json_decode($jsonData, true) : [];
if ($data && Carbon::now()->timestamp < $data['resend_expire']) {
$this->retError( '簡訊已在1分鐘內發出,請耐心等');
}
// 手機號限制
$sendCnt = $redis->zScore($limitKey, $phone);
if ($sendCnt && $sendCnt >= env('ONE_DAY_FREQ', 1)) {
$this->retError("獲取驗證碼次數已達上限");
}
//生成4位驗證碼
$code = $this->createVerifyCode($phone);
//傳送簡訊獲取驗證碼
app(HttpService::class)->sendSms($phone,$code);
//redis中儲存驗證碼
$this->saveSmsCode($phone, $code, $key, $limitKey);
}
public function saveSmsCode(string $phone, string $code, string $key, string $limitKey)
{
$redis = Hope::getRedis();
$data = [
'code' => $code,
'resend_expire' => Carbon::now()->addSeconds(env('RESEND_SEC', 60))->timestamp,
];
$redis->set($key, json_encode($data));
$redis->expire($key, (int) env('EXPIRE_SEC', 1800)); // 設定驗證碼過期時間
// 設定手機號限制
$redis->zIncrBy($limitKey, 1, $phone);
$redis->expireAt($limitKey, (int) Carbon::today()->addDay()->timestamp);
if (! Hope::isProduct()) {
return true;
}
}
/**
* 驗證簡訊驗證碼
* @param string $phone 手機號
* @param string $code 驗證碼
* @return bool
*/
public function checkSmsCode(string $phone, string $code): bool
{
$testSmsCode = config('constant.sms_code');
if (env('APP_ENV', 'dev') != 'prod' && $code == $testSmsCode) {
return true;
}
$arr = [$testSmsCode, $this->createVerifyCode($phone)];
if (!Hope::isProduct() && in_array($code, $arr )) {
return true;
}
$key = $this->getKey($phone);
$jsonData = Hope::getRedis()->get($key);
$data = $jsonData ? json_decode($jsonData, true) : [];
if ($data && $code === $data['code']) {
return true;
}
$this->retError("驗證碼有誤,請重新輸入!");
}
/**
* @param string $phone 手機號
* @return string
*/
private function getKey(string $phone): string
{
return "code:" . $phone;
}
/**
* 建立4位驗證碼
* @param string $phone 手機號
* @return string
*/
private function createVerifyCode(string $phone): string
{
if(!Hope::isProduct()){
return substr($phone, -4);
}
return (string)mt_rand(1000, 9999);
}
}
順便把公共函式貼出來
<?php
namespace Framework;
use App\Services\UploadService;
use Illuminate\Redis\Connections\PhpRedisConnection;
use Illuminate\Support\Facades\Redis;
use SimpleSoftwareIO\QrCode\BaconQrCodeGenerator;
class Hope
{
public static function isProduct(): bool
{
$env = env('APP_ENV', 'local');
if ($env === 'prod') {
return true;
}
return false;
}
public static function getRedis(string $connection = 'default'): PhpRedisConnection
{
/** @var PhpRedisConnection $redis */
$redis = Redis::connection($connection);
return $redis;
}
public static function getLoginId(): int
{
$jwt = app(Jwt::class);
$user_id = $jwt->checkToken();
if ($user_id === false) {
return 0;
}
return $user_id;
}
/**
* 獲取隨機邀請碼
* @return string
*/
public static function makeInviterCode() {
$code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$rand = $code[rand(0,25)]
.strtoupper(dechex(date('m')))
.date('d').substr(time(),-5)
.substr(microtime(),2,5)
.sprintf('%02d',rand(0,99));
for(
$a = md5( $rand, true ),
$s = '0123456789ABCDEFGHIJKLMNOPQRSTUV',
$d = '',
$f = 0;
$f < 8;
$g = ord( $a[ $f ] ),
$d .= $s[ ( $g ^ ord( $a[ $f + 8 ] ) ) - $g & 0x1F ],
$f++
);
return $d;
}
/**
* 建立二維碼
* @param $inviterCode
* @return string
*/
public static function makeInviterQrcode($inviterCode)
{
$text = $_SERVER["HTTP_HOST"] . '/app.apk';
$size = 200;
//$img = public_path('/logo.png');
$qr = new BaconQrCodeGenerator();
$img = $qr->format('png')->size($size)->margin(1)->generate($text);
$type = 'qrcode';
$path = app(UploadService::class)->uploadQiniu($img,$type,$inviterCode);
return $path;
}
/**
* @param string $prefix
* @return string
*/
public static function random_order($prefix='MC')
{
return $prefix . date('YmdHis', time()) . substr(microtime(), 2, 6) . sprintf('%03d', rand(0, 999));
}
public static function name_auth($name,$id_card){
$host = "https://idcert.market.alicloudapi.com";
$path = "/idcard";
$method = "GET";
$appcode = "111111111111111111111";//開通服務後 買家中心-檢視AppCode
$headers = array();
array_push($headers, "Authorization:APPCODE " . $appcode);
$querys = "idCard={$id_card}&name=".urlencode($name);
$bodys = "";
$url = $host . $path . "?" . $querys;
$curl = curl_init();
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_FAILONERROR, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, true);
if (1 == strpos("$" . $host, "https://")) {
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
}
$out_put = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
list($header, $body) = explode("\r\n\r\n", $out_put, 2);
if ($httpCode == 200) {
return $body;
}
}
}
最後簡訊基類
<?php
namespace App\Services\Sms;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use Framework\BaseService;
use Framework\Hope;
class HttpService extends BaseService
{
/** 阿里簡訊配置
* @param string $phone
* @param string $code
* @return bool
* @throws ClientException
*/
public function sendSms(string $phone, string $code)
{
if(!Hope::isProduct()){
return true;
}
$accessKey = env('ALIYUN_SMS_ACCESS_KEY');
$secretKey = env('ALIYUN_SMS_ACCESS_SECRET');
$query = [
'PhoneNumbers' => $phone,
'SignName' => env('ALIYUN_SMS_SIGN_NAME'),
'TemplateCode' => env('ALIYUN_SMS_SEND_CODE'),
'TemplateParam' => json_encode(['code' => $code]),
];
AlibabaCloud::accessKeyClient($accessKey, $secretKey)
->regionId('cn-hangzhou')
->asDefaultClient();
try {
$result = AlibabaCloud::rpc()
->product('Dysmsapi')
->scheme('https')
->version('2017-05-25')
->action('SendSms')
->method('POST')
->host('dysmsapi.aliyuncs.com')
->options([
'query' => $query
])
->request();
} catch (ClientException $e) {
$this->retError("簡訊傳送失敗");
} catch (ServerException $e) {
$this->retError("簡訊傳送失敗");
}
$result = $result->toArray();
if ($result['Code'] == 'OK') {
return true;
} else {
$this->retError("簡訊傳送失敗");
}
}
}
最後在推薦一個類也很好用哦,有興趣可以去了解一下
overtrue/easy-sms
本作品採用《CC 協議》,轉載必須註明作者和本文連結