最近公司切换阿里云短信服务,只能用新的sdk,官方的api接口说明太简单了,sdk太乱了
官方提供的属实太乱太冗余了
虽然使用composer看似简单,但是包真的很大,本人不才,查了很多资料,总结了一下,简单明了,100多行代码,解决阿里云短信发送问题,与大家共勉
使用步骤
1. 开通短信服务
这个就不用多说了,自行解决吧
2. 申请短信签名
短信服务发送的短信中包括短信签名和短信模板。短信签名是短信发送者的署名,表示发送方的身份;短信模板是发送的短信内容。
使用短信签名和短信模板前必须提交短信服务审核,审核通过的签名和模板才能使用在短信中。
申请短信签名,请参考以下文档在控制台签名管理页面操作:
添加签名
签名规范
个人用户签名规范
企业用户签名规范
签名审核
3. 申请短信模板
短信模板是发送的短信内容。短信分为国内短信和国际港澳台短信,其中国内短信包括验证码短信、短信通知和推广短信,不同类型的短信使用不同的短信模板,遵循不同的模板规范。
申请短信模板,请参考以下文在控制台模板管理页面档操作:
添加文本短信模板
添加国际/港澳台短信模板(企业用户)
签名规范
文本短信模板规范
国际/港澳台短信模板规范
模板审核流程
4. 发送短信
最重要的步骤来啦,看完官方文档后,还是直接copy下面的代码使用吧
/**
* 阿里云短信发送类
* @author Arrow
* 参考:https://www.cnblogs.com/zxf100/archive/2019/09/06/11473662.html
*/
class aliyunsms{
// 保存错误信息
public $error;
// Access Key ID
private $accessKeyId = '';
// Access Access Key Secret
private $accessKeySecret = '';
// 签名
private $signName = '';
// 模版ID
private $templateCode = '';
public function __construct($signName) {
$config = array (
'accessKeyId' => '',
'accessKeySecret' => '',
'signName' => $signName,
);
// 配置参数
$this->accessKeyId= $config['accessKeyId'];
$this->accessKeySecret= $config['accessKeySecret'];
$this->signName= $config['signName'];
}
private function percentEncode($string) {
$string = urlencode ($string );
$string = preg_replace ('/\+/', '%20', $string );
$string = preg_replace ('/\*/', '%2A', $string );
$string = preg_replace ('/%7E/', '~', $string );
return $string;
}
/**
* 签名
*
* @param unknown $parameters
* @param unknown $accessKeySecret
* @return string
*/
private function computeSignature($parameters, $accessKeySecret) {
ksort ($parameters );
$canonicalizedQueryString = '';
foreach ($parameters as $key => $value ) {
$canonicalizedQueryString .= '&' . $this->percentEncode ($key ). '=' . $this->percentEncode ($value );
}
$stringToSign = 'GET&%2F&' . $this->percentencode ( substr ($canonicalizedQueryString, 1 ) );
$signature = base64_encode ( hash_hmac ('sha1', $stringToSign, $accessKeySecret . '&', true ) );
return $signature;
}
/**
* Notes:发送模板消息
* User: Arrow
* Date: 2019-11-13
* Time: 15:16
*
* @param $templateCode 短信模板ID
* @param $mobile 接收短信的手机号码
* @param array $templateParam 短信模板变量对应的实际值,数组格式
* @return bool
*/
public function send_message($templateCode,$mobile, $templateParam=array()) {
$params = array (//此处作了修改
'SignName' => $this->signName,
'Format' => 'JSON',
'Version' => '2017-05-25',
'AccessKeyId' => $this->accessKeyId,
'SignatureVersion' => '1.0',
'SignatureMethod' => 'HMAC-SHA1',
'SignatureNonce' => uniqid (),
'Timestamp' => gmdate ('Y-m-d\TH:i:s\Z' ),
'Action' => 'SendSms',
'TemplateCode' => $templateCode,
'PhoneNumbers' => $mobile,
'TemplateParam' => json_encode($templateParam)//更换为自己的实际模版
);
//var_dump($params);die;
// 计算签名并把签名结果加入请求参数
$params ['Signature']= $this->computeSignature ($params, $this->accessKeySecret );
// 发送请求(此处作了修改)
$url = 'https://dysmsapi.aliyuncs.com?' . http_build_query ($params );
$ch = curl_init ();
curl_setopt ($ch, CURLOPT_URL, $url );
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, FALSE );
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, FALSE );
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt ($ch, CURLOPT_TIMEOUT, 10 );
$result = curl_exec ($ch );
curl_close ($ch );
$result = json_decode ($result, true );
log_message('debug',__METHOD__.' '.__LINE__.'行,发送短信结果为=》'.var_export($result,true));
//var_dump($result);die;
if (isset ($result ['Code'] )) {
$this->error= $this->getErrorMessage ($result ['Code'] );
log_message('debug',__METHOD__.' '.__LINE__.'行,发送短信结果error为=》'.var_export($this->error,true));
return false;
}
return true;
}
/**
* 获取详细错误信息
*
* @param unknown $status
*/
public function getErrorMessage($status) {
// 阿里云的短信 乱八七糟的(其实是用的阿里大于)
// https://api.alidayu.com/doc2/apiDetail?spm=a3142.7629140.1.19.SmdYoA&apiId=25450
$message = array (
'InvalidDayuStatus.Malformed' => '账户短信开通状态不正确',
'InvalidSignName.Malformed' => '短信签名不正确或签名状态不正确',
'InvalidTemplateCode.MalFormed' => '短信模板Code不正确或者模板状态不正确',
'InvalidRecNum.Malformed' => '目标手机号不正确,单次发送数量不能超过100',
'InvalidParamString.MalFormed' => '短信模板中变量不是json格式',
'InvalidParamStringTemplate.Malformed' => '短信模板中变量与模板内容不匹配',
'InvalidSendSms' => '触发业务流控',
'InvalidDayu.Malformed' => '变量不能是url,可以将变量固化在模板中'
);
if (isset ($message [$status] )) {
return $message [$status];
}
return $status;
}
}
遇到的坑之点滴:
你以为按照官方给出的步骤就能成了吗,too young to simple
反正我这个不行,一直提示:isp.RAM_PERMISSION_DENY
原因:RAM权限不足。
解决方案:请为当前使用的AK对应子账号进行授权:AliyunDysmsFullAccess(管理权限)。具体操作请参考:访问权限控制。 链接还打不开,醉了
去RAM中把该用户的权限添加上短信相关的权限