Commit 4546c1c7 authored by 冯超鹏's avatar 冯超鹏

提交 短信发送

parent 59c6d81a
Pipeline #239 canceled with stages
......@@ -10,7 +10,7 @@ use Illuminate\Support\Facades\Redis;
use App\Http\Controllers\DevicesController;
use Illuminate\Support\Facades\Config;
use App\Http\Controllers\Auth\SwooleCommandMeTcpController;
use App\Http\Controllers\SmsailiyunController;
class ZehongTcpController extends Controller
{
......@@ -90,7 +90,7 @@ class ZehongTcpController extends Controller
$meTcp = new SwooleCommandMeTcpController();
$alarmData = $data['id'] . '/' . $data['status'] . '/' . $data['np'];
$meTcp->swooletcplist($alarmData);
$this->smsphone($data);
$datainfo = DB::table('device')
->where('devicenum','=',$data['id'])
->update(['nd'=>intval($data['np']),'devicepolice'=>$data['status'] == 0 ? '1' : $data['status'],'update_time'=>time(),'shutoff_status'=>$data['famen']]);
......@@ -106,4 +106,17 @@ class ZehongTcpController extends Controller
}
}
// 发送手机报警信息
public function smsphone($data){
if(Redis::get('smsyanshi') != ''){
if($data['status'] != 1 || $data['status'] != 0){
$sms = new SmsailiyunController();
$code = json_encode($sms->sendSms(),true);
if($code['Message'] == 'OK' && $code['Code'] == 'OK'){
Redis::set('smsyanshi',$code);
}
}
}
}
}
<?php
namespace App\Http\Controllers;
require_once app_path() . '/aliyunsdk/api_sdk/vendor/autoload.php';
use Aliyun\Core\Config;
use Aliyun\Core\Profile\DefaultProfile;
use Aliyun\Core\DefaultAcsClient;
use Aliyun\Api\Sms\Request\V20170525\SendSmsRequest;
use Aliyun\Api\Sms\Request\V20170525\SendBatchSmsRequest;
use Aliyun\Api\Sms\Request\V20170525\QuerySendDetailsRequest;
Config::load();
class SmsailiyunController
{
static $acsClient = null;
/**
* 取得AcsClient
*
* @return DefaultAcsClient
*/
public static function getAcsClient() {
//产品名称:云通信短信服务API产品,开发者无需替换
$product = "Dysmsapi";
//产品域名,开发者无需替换
$domain = "https://dysmsapi.aliyuncs.com";
$accessKeyId = "LTAI2xiZNF3iV2aV"; // AccessKeyId
$accessKeySecret = "bprEWwn1M0xgglRQCQEMYSPiYctDk4"; // AccessKeySecret
// 暂时不支持多Region
$region = "cn-beijing";
// 服务结点
$endPointName = "cn-hangzhou";
if(static::$acsClient == null) {
//初始化acsClient,暂不支持region化
$profile = DefaultProfile::getProfile($region, $accessKeyId, $accessKeySecret);
// 增加服务结点
DefaultProfile::addEndpoint($endPointName, $region, $product, $domain);
// 初始化AcsClient用于发起请求
static::$acsClient = new DefaultAcsClient($profile);
}
return static::$acsClient;
}
/**
* 发送短信
* @return stdClass
*/
public static function sendSms() {
// 初始化SendSmsRequest实例用于设置发送短信的参数
$request = new SendSmsRequest();
//可选-启用https协议
//$request->setProtocol("https");
// 必填,设置短信接收号码
// 15200013720
$request->setPhoneNumbers("16631150870");
// 必填,设置签名名称,应严格按"签名名称"填写,请参考: https://dysms.console.aliyun.com/dysms.htm#/develop/sign
$request->setSignName("泽宏云");
// 必填,设置模板CODE,应严格按"模板CODE"填写, 请参考: https://dysms.console.aliyun.com/dysms.htm#/develop/template
$request->setTemplateCode("SMS_169897307");
// 可选,设置模板参数, 假如模板中存在变量需要替换则为必填项
$request->setTemplateParam(json_encode(array( // 短信模板中字段的值
"cphone"=>"16631150870",
"position"=>"您的设备尾号为" . 5712,
"alarm" => '离线'
), JSON_UNESCAPED_UNICODE));
// ['cphone' => 16631150870, 'position' => '您的设备尾号为' . 5712, 'alarm' => '离线']
// 可选,设置流水号
$request->setOutId("yourOutId");
// 选填,上行短信扩展码(扩展码字段控制在7位或以下,无特殊需求用户请忽略此字段)
$request->setSmsUpExtendCode("1234567");
// 发起访问请求
$acsResponse = static::getAcsClient()->getAcsResponse($request);
return $acsResponse;
}
/**
* 批量发送短信
* @return stdClass
*/
public static function sendBatchSms() {
// 初始化SendSmsRequest实例用于设置发送短信的参数
$request = new SendBatchSmsRequest();
//可选-启用https协议
//$request->setProtocol("https");
// 必填:待发送手机号。支持JSON格式的批量调用,批量上限为100个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式
$request->setPhoneNumberJson(json_encode(array(
"1500000000",
"1500000001",
), JSON_UNESCAPED_UNICODE));
// 必填:短信签名-支持不同的号码发送不同的短信签名
$request->setSignNameJson(json_encode(array(
"云通信",
"云通信"
), JSON_UNESCAPED_UNICODE));
// 必填:短信模板-可在短信控制台中找到
$request->setTemplateCode("SMS_1000000");
// 必填:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
// 友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败
$request->setTemplateParamJson(json_encode(array(
array(
"name" => "Tom",
"code" => "123",
),
array(
"name" => "Jack",
"code" => "456",
),
), JSON_UNESCAPED_UNICODE));
// 可选-上行短信扩展码(扩展码字段控制在7位或以下,无特殊需求用户请忽略此字段)
// $request->setSmsUpExtendCodeJson("[\"90997\",\"90998\"]");
// 发起访问请求
$acsResponse = static::getAcsClient()->getAcsResponse($request);
return $acsResponse;
}
/**
* 短信发送记录查询
* @return stdClass
*/
public static function querySendDetails() {
// 初始化QuerySendDetailsRequest实例用于设置短信查询的参数
$request = new QuerySendDetailsRequest();
//可选-启用https协议
//$request->setProtocol("https");
// 必填,短信接收号码
$request->setPhoneNumber("12345678901");
// 必填,短信发送日期,格式Ymd,支持近30天记录查询
$request->setSendDate("20170718");
// 必填,分页大小
$request->setPageSize(10);
// 必填,当前页码
$request->setCurrentPage(1);
// 选填,短信发送流水号
$request->setBizId("yourBizId");
// 发起访问请求
$acsResponse = static::getAcsClient()->getAcsResponse($request);
return $acsResponse;
}
}
......@@ -25,6 +25,7 @@ use Illuminate\Support\Facades\DB;
use Illuminate\Support\Env;
use Illuminate\Support\Facades\Hash;
use Validator;
use App\Http\Controllers\SmsailiyunController;
/**
* Class UserController
......@@ -465,12 +466,12 @@ class UserController extends Controller
if ($areaid == '') {
return $this->jsonErrorData('105', '地区id不能为空');
}
$area = Db::table('areachina')->where('pid', '=', $areaid)
$area = Db::table('areachina')->where('pid', '=', $areaid)
->where('status', '=', '1')
->select('area_name', 'areaid')
->get();
} else {
$area = Db::table('areachina')->where('pid', '=', '0')
$area = Db::table('areachina')->where('pid', '=', '0')
->where('status', '=', '1')
->select('area_name', 'areaid')
->get();
......@@ -542,7 +543,7 @@ class UserController extends Controller
->get()->toArray();
} else {
$davicenum = DB::table('users as b')
->where('uid','=',Auth::id())
->where('uid', '=', Auth::id())
->leftjoin('device as d', 'b.id', '=', 'd.uid')
->leftjoin('device_type as t', 'd.dtype', '=', 't.tid')
->selectRaw('b.name,b.id,b.mapcenter,d.devicenum,COUNT(d.id) AS UserDaviceNum,COUNT(IF(d.devicepolice <> 1, true, null)) AS police')
......@@ -562,8 +563,10 @@ class UserController extends Controller
return $this->jsonSuccessData(['paper' => $paper, 'stutus' => $stutus]);
}
public function textcountuser()
public function textcountuser(Request $request)
{
print_r(Auth::id());
// https://dysmsapi.aliyuncs.com?
// $sms = new SmsailiyunController();
// print_r(json_encode($sms->sendSms(),true));
}
}
<?php
ini_set("display_errors", "on");
require_once dirname(__DIR__) . '/api_sdk/vendor/autoload.php';
use Aliyun\Core\Config;
use Aliyun\Core\Profile\DefaultProfile;
use Aliyun\Core\DefaultAcsClient;
use Aliyun\Api\Sms\Request\V20170525\SendSmsRequest;
use Aliyun\Api\Sms\Request\V20170525\SendBatchSmsRequest;
use Aliyun\Api\Sms\Request\V20170525\QuerySendDetailsRequest;
// 加载区域结点配置
Config::load();
/**
* Class SmsDemo
*
* 这是短信服务API产品的DEMO程序,直接执行此文件即可体验短信服务产品API功能
* (只需要将AK替换成开通了云通信-短信服务产品功能的AK即可)
* 备注:Demo工程编码采用UTF-8
*/
class SmsDemo
{
static $acsClient = null;
/**
* 取得AcsClient
*
* @return DefaultAcsClient
*/
public static function getAcsClient() {
//产品名称:云通信短信服务API产品,开发者无需替换
$product = "Dysmsapi";
//产品域名,开发者无需替换
$domain = "dysmsapi.aliyuncs.com";
// TODO 此处需要替换成开发者自己的AK (https://ak-console.aliyun.com/)
$accessKeyId = "yourAccessKeyId"; // AccessKeyId
$accessKeySecret = "yourAccessKeySecret"; // AccessKeySecret
// 暂时不支持多Region
$region = "cn-hangzhou";
// 服务结点
$endPointName = "cn-hangzhou";
if(static::$acsClient == null) {
//初始化acsClient,暂不支持region化
$profile = DefaultProfile::getProfile($region, $accessKeyId, $accessKeySecret);
// 增加服务结点
DefaultProfile::addEndpoint($endPointName, $region, $product, $domain);
// 初始化AcsClient用于发起请求
static::$acsClient = new DefaultAcsClient($profile);
}
return static::$acsClient;
}
/**
* 发送短信
* @return stdClass
*/
public static function sendSms() {
// 初始化SendSmsRequest实例用于设置发送短信的参数
$request = new SendSmsRequest();
//可选-启用https协议
//$request->setProtocol("https");
// 必填,设置短信接收号码
$request->setPhoneNumbers("12345678901");
// 必填,设置签名名称,应严格按"签名名称"填写,请参考: https://dysms.console.aliyun.com/dysms.htm#/develop/sign
$request->setSignName("短信签名");
// 必填,设置模板CODE,应严格按"模板CODE"填写, 请参考: https://dysms.console.aliyun.com/dysms.htm#/develop/template
$request->setTemplateCode("SMS_0000001");
// 可选,设置模板参数, 假如模板中存在变量需要替换则为必填项
$request->setTemplateParam(json_encode(array( // 短信模板中字段的值
"code"=>"12345",
"product"=>"dsd"
), JSON_UNESCAPED_UNICODE));
// 可选,设置流水号
$request->setOutId("yourOutId");
// 选填,上行短信扩展码(扩展码字段控制在7位或以下,无特殊需求用户请忽略此字段)
$request->setSmsUpExtendCode("1234567");
// 发起访问请求
$acsResponse = static::getAcsClient()->getAcsResponse($request);
return $acsResponse;
}
/**
* 批量发送短信
* @return stdClass
*/
public static function sendBatchSms() {
// 初始化SendSmsRequest实例用于设置发送短信的参数
$request = new SendBatchSmsRequest();
//可选-启用https协议
//$request->setProtocol("https");
// 必填:待发送手机号。支持JSON格式的批量调用,批量上限为100个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式
$request->setPhoneNumberJson(json_encode(array(
"1500000000",
"1500000001",
), JSON_UNESCAPED_UNICODE));
// 必填:短信签名-支持不同的号码发送不同的短信签名
$request->setSignNameJson(json_encode(array(
"云通信",
"云通信"
), JSON_UNESCAPED_UNICODE));
// 必填:短信模板-可在短信控制台中找到
$request->setTemplateCode("SMS_1000000");
// 必填:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
// 友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败
$request->setTemplateParamJson(json_encode(array(
array(
"name" => "Tom",
"code" => "123",
),
array(
"name" => "Jack",
"code" => "456",
),
), JSON_UNESCAPED_UNICODE));
// 可选-上行短信扩展码(扩展码字段控制在7位或以下,无特殊需求用户请忽略此字段)
// $request->setSmsUpExtendCodeJson("[\"90997\",\"90998\"]");
// 发起访问请求
$acsResponse = static::getAcsClient()->getAcsResponse($request);
return $acsResponse;
}
/**
* 短信发送记录查询
* @return stdClass
*/
public static function querySendDetails() {
// 初始化QuerySendDetailsRequest实例用于设置短信查询的参数
$request = new QuerySendDetailsRequest();
//可选-启用https协议
//$request->setProtocol("https");
// 必填,短信接收号码
$request->setPhoneNumber("12345678901");
// 必填,短信发送日期,格式Ymd,支持近30天记录查询
$request->setSendDate("20170718");
// 必填,分页大小
$request->setPageSize(10);
// 必填,当前页码
$request->setCurrentPage(1);
// 选填,短信发送流水号
$request->setBizId("yourBizId");
// 发起访问请求
$acsResponse = static::getAcsClient()->getAcsResponse($request);
return $acsResponse;
}
}
// 调用示例:
set_time_limit(0);
header('Content-Type: text/plain; charset=utf-8');
$response = SmsDemo::sendSms();
echo "发送短信(sendSms)接口返回的结果:\n";
print_r($response);
sleep(2);
$response = SmsDemo::sendBatchSms();
echo "批量发送短信(sendBatchSms)接口返回的结果:\n";
print_r($response);
sleep(2);
$response = SmsDemo::querySendDetails();
echo "查询短信发送情况(querySendDetails)接口返回的结果:\n";
print_r($response);
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
{
"name": "aliyuncs/aliyun-dysms-php-sdk",
"description": "Aliyun SMS SDK for PHP",
"keywords": [ "aliyun", "SMS", "sdk" ],
"type": "library",
"license": "Apache-2.0",
"homepage": "https://www.aliyun.com/product/sms",
"authors": [
{
"name": "Aliyuncs",
"homepage": "https://www.aliyun.com"
}
],
"require": {
"php": ">=5.5.0"
},
"require-dev": {},
"minimum-stability": "stable",
"autoload": {
"psr-4": {
"Aliyun\\": "lib/"
}
}
}
\ No newline at end of file
<?php
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
namespace Aliyun\Api\Sms\Request\V20170525;
use Aliyun\Core\RpcAcsRequest;
class QueryInterSmsIsoInfoRequest extends RpcAcsRequest
{
function __construct()
{
parent::__construct("Dysmsapi", "2017-05-25", "QueryInterSmsIsoInfo");
$this->setMethod("POST");
}
private $resourceOwnerAccount;
private $countryName;
private $resourceOwnerId;
private $ownerId;
public function getResourceOwnerAccount() {
return $this->resourceOwnerAccount;
}
public function setResourceOwnerAccount($resourceOwnerAccount) {
$this->resourceOwnerAccount = $resourceOwnerAccount;
$this->queryParameters["ResourceOwnerAccount"]=$resourceOwnerAccount;
}
public function getCountryName() {
return $this->countryName;
}
public function setCountryName($countryName) {
$this->countryName = $countryName;
$this->queryParameters["CountryName"]=$countryName;
}
public function getResourceOwnerId() {
return $this->resourceOwnerId;
}
public function setResourceOwnerId($resourceOwnerId) {
$this->resourceOwnerId = $resourceOwnerId;
$this->queryParameters["ResourceOwnerId"]=$resourceOwnerId;
}
public function getOwnerId() {
return $this->ownerId;
}
public function setOwnerId($ownerId) {
$this->ownerId = $ownerId;
$this->queryParameters["OwnerId"]=$ownerId;
}
}
\ No newline at end of file
<?php
namespace Aliyun\Api\Sms\Request\V20170525;
use Aliyun\Core\RpcAcsRequest;
class QuerySendDetailsRequest extends RpcAcsRequest
{
function __construct()
{
parent::__construct("Dysmsapi", "2017-05-25", "QuerySendDetails");
$this->setMethod("POST");
}
private $sendDate;
private $pageSize;
private $phoneNumber;
private $resourceOwnerAccount;
private $currentPage;
private $bizId;
private $resourceOwnerId;
private $ownerId;
public function getSendDate() {
return $this->sendDate;
}
public function setSendDate($sendDate) {
$this->sendDate = $sendDate;
$this->queryParameters["SendDate"]=$sendDate;
}
public function getPageSize() {
return $this->pageSize;
}
public function setPageSize($pageSize) {
$this->pageSize = $pageSize;
$this->queryParameters["PageSize"]=$pageSize;
}
public function getPhoneNumber() {
return $this->phoneNumber;
}
public function setPhoneNumber($phoneNumber) {
$this->phoneNumber = $phoneNumber;
$this->queryParameters["PhoneNumber"]=$phoneNumber;
}
public function getResourceOwnerAccount() {
return $this->resourceOwnerAccount;
}
public function setResourceOwnerAccount($resourceOwnerAccount) {
$this->resourceOwnerAccount = $resourceOwnerAccount;
$this->queryParameters["ResourceOwnerAccount"]=$resourceOwnerAccount;
}
public function getCurrentPage() {
return $this->currentPage;
}
public function setCurrentPage($currentPage) {
$this->currentPage = $currentPage;
$this->queryParameters["CurrentPage"]=$currentPage;
}
public function getBizId() {
return $this->bizId;
}
public function setBizId($bizId) {
$this->bizId = $bizId;
$this->queryParameters["BizId"]=$bizId;
}
public function getResourceOwnerId() {
return $this->resourceOwnerId;
}
public function setResourceOwnerId($resourceOwnerId) {
$this->resourceOwnerId = $resourceOwnerId;
$this->queryParameters["ResourceOwnerId"]=$resourceOwnerId;
}
public function getOwnerId() {
return $this->ownerId;
}
public function setOwnerId($ownerId) {
$this->ownerId = $ownerId;
$this->queryParameters["OwnerId"]=$ownerId;
}
}
\ No newline at end of file
<?php
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
namespace Aliyun\Api\Sms\Request\V20170525;
use Aliyun\Core\RpcAcsRequest;
class SendBatchSmsRequest extends RpcAcsRequest
{
function __construct()
{
parent::__construct("Dysmsapi", "2017-05-25", "SendBatchSms");
$this->setMethod("POST");
}
private $templateCode;
private $templateParamJson;
private $resourceOwnerAccount;
private $smsUpExtendCodeJson;
private $resourceOwnerId;
private $signNameJson;
private $ownerId;
private $phoneNumberJson;
public function getTemplateCode() {
return $this->templateCode;
}
public function setTemplateCode($templateCode) {
$this->templateCode = $templateCode;
$this->queryParameters["TemplateCode"]=$templateCode;
}
public function getTemplateParamJson() {
return $this->templateParamJson;
}
public function setTemplateParamJson($templateParamJson) {
$this->templateParamJson = $templateParamJson;
$this->queryParameters["TemplateParamJson"]=$templateParamJson;
}
public function getResourceOwnerAccount() {
return $this->resourceOwnerAccount;
}
public function setResourceOwnerAccount($resourceOwnerAccount) {
$this->resourceOwnerAccount = $resourceOwnerAccount;
$this->queryParameters["ResourceOwnerAccount"]=$resourceOwnerAccount;
}
public function getSmsUpExtendCodeJson() {
return $this->smsUpExtendCodeJson;
}
public function setSmsUpExtendCodeJson($smsUpExtendCodeJson) {
$this->smsUpExtendCodeJson = $smsUpExtendCodeJson;
$this->queryParameters["SmsUpExtendCodeJson"]=$smsUpExtendCodeJson;
}
public function getResourceOwnerId() {
return $this->resourceOwnerId;
}
public function setResourceOwnerId($resourceOwnerId) {
$this->resourceOwnerId = $resourceOwnerId;
$this->queryParameters["ResourceOwnerId"]=$resourceOwnerId;
}
public function getSignNameJson() {
return $this->signNameJson;
}
public function setSignNameJson($signNameJson) {
$this->signNameJson = $signNameJson;
$this->queryParameters["SignNameJson"]=$signNameJson;
}
public function getOwnerId() {
return $this->ownerId;
}
public function setOwnerId($ownerId) {
$this->ownerId = $ownerId;
$this->queryParameters["OwnerId"]=$ownerId;
}
public function getPhoneNumberJson() {
return $this->phoneNumberJson;
}
public function setPhoneNumberJson($phoneNumberJson) {
$this->phoneNumberJson = $phoneNumberJson;
$this->queryParameters["PhoneNumberJson"]=$phoneNumberJson;
}
}
\ No newline at end of file
<?php
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
namespace Aliyun\Api\Sms\Request\V20170525;
use Aliyun\Core\RpcAcsRequest;
class SendInterSmsRequest extends RpcAcsRequest
{
function __construct()
{
parent::__construct("Dysmsapi", "2017-05-25", "SendInterSms");
$this->setMethod("POST");
}
private $templateCode;
private $phoneNumbers;
private $countryCode;
private $signName;
private $resourceOwnerAccount;
private $templateParam;
private $resourceOwnerId;
private $ownerId;
private $outId;
public function getTemplateCode() {
return $this->templateCode;
}
public function setTemplateCode($templateCode) {
$this->templateCode = $templateCode;
$this->queryParameters["TemplateCode"]=$templateCode;
}
public function getPhoneNumbers() {
return $this->phoneNumbers;
}
public function setPhoneNumbers($phoneNumbers) {
$this->phoneNumbers = $phoneNumbers;
$this->queryParameters["PhoneNumbers"]=$phoneNumbers;
}
public function getCountryCode() {
return $this->countryCode;
}
public function setCountryCode($countryCode) {
$this->countryCode = $countryCode;
$this->queryParameters["CountryCode"]=$countryCode;
}
public function getSignName() {
return $this->signName;
}
public function setSignName($signName) {
$this->signName = $signName;
$this->queryParameters["SignName"]=$signName;
}
public function getResourceOwnerAccount() {
return $this->resourceOwnerAccount;
}
public function setResourceOwnerAccount($resourceOwnerAccount) {
$this->resourceOwnerAccount = $resourceOwnerAccount;
$this->queryParameters["ResourceOwnerAccount"]=$resourceOwnerAccount;
}
public function getTemplateParam() {
return $this->templateParam;
}
public function setTemplateParam($templateParam) {
$this->templateParam = $templateParam;
$this->queryParameters["TemplateParam"]=$templateParam;
}
public function getResourceOwnerId() {
return $this->resourceOwnerId;
}
public function setResourceOwnerId($resourceOwnerId) {
$this->resourceOwnerId = $resourceOwnerId;
$this->queryParameters["ResourceOwnerId"]=$resourceOwnerId;
}
public function getOwnerId() {
return $this->ownerId;
}
public function setOwnerId($ownerId) {
$this->ownerId = $ownerId;
$this->queryParameters["OwnerId"]=$ownerId;
}
public function getOutId() {
return $this->outId;
}
public function setOutId($outId) {
$this->outId = $outId;
$this->queryParameters["OutId"]=$outId;
}
}
\ No newline at end of file
<?php
namespace Aliyun\Api\Sms\Request\V20170525;
use Aliyun\Core\RpcAcsRequest;
class SendSmsRequest extends RpcAcsRequest
{
public function __construct()
{
parent::__construct("Dysmsapi", "2017-05-25", "SendSms");
$this->setMethod("POST");
}
private $templateCode;
private $phoneNumbers;
private $signName;
private $resourceOwnerAccount;
private $templateParam;
private $resourceOwnerId;
private $ownerId;
private $outId;
private $smsUpExtendCode;
public function getTemplateCode() {
return $this->templateCode;
}
public function setTemplateCode($templateCode) {
$this->templateCode = $templateCode;
$this->queryParameters["TemplateCode"]=$templateCode;
}
public function getPhoneNumbers() {
return $this->phoneNumbers;
}
public function setPhoneNumbers($phoneNumbers) {
$this->phoneNumbers = $phoneNumbers;
$this->queryParameters["PhoneNumbers"]=$phoneNumbers;
}
public function getSignName() {
return $this->signName;
}
public function setSignName($signName) {
$this->signName = $signName;
$this->queryParameters["SignName"]=$signName;
}
public function getResourceOwnerAccount() {
return $this->resourceOwnerAccount;
}
public function setResourceOwnerAccount($resourceOwnerAccount) {
$this->resourceOwnerAccount = $resourceOwnerAccount;
$this->queryParameters["ResourceOwnerAccount"]=$resourceOwnerAccount;
}
public function getTemplateParam() {
return $this->templateParam;
}
public function setTemplateParam($templateParam) {
$this->templateParam = $templateParam;
$this->queryParameters["TemplateParam"]=$templateParam;
}
public function getResourceOwnerId() {
return $this->resourceOwnerId;
}
public function setResourceOwnerId($resourceOwnerId) {
$this->resourceOwnerId = $resourceOwnerId;
$this->queryParameters["ResourceOwnerId"]=$resourceOwnerId;
}
public function getOwnerId() {
return $this->ownerId;
}
public function setOwnerId($ownerId) {
$this->ownerId = $ownerId;
$this->queryParameters["OwnerId"]=$ownerId;
}
public function getOutId() {
return $this->outId;
}
public function setOutId($outId) {
$this->outId = $outId;
$this->queryParameters["OutId"]=$outId;
}
public function getSmsUpExtendCode() {
return $this->smsUpExtendCode;
}
public function setSmsUpExtendCode($smsUpExtendCode) {
$this->smsUpExtendCode = $smsUpExtendCode;
$this->queryParameters["SmsUpExtendCode"]=$smsUpExtendCode;
}
}
\ No newline at end of file
<?php
namespace Aliyun\Core;
abstract class AcsRequest
{
protected $version;
protected $product;
protected $actionName;
protected $regionId;
protected $acceptFormat;
protected $method;
protected $protocolType = "http";
protected $content;
protected $queryParameters = array();
protected $headers = array();
function __construct($product, $version, $actionName)
{
$this->headers["x-sdk-client"] = "php/2.0.0";
$this->product = $product;
$this->version = $version;
$this->actionName = $actionName;
}
public abstract function composeUrl($iSigner, $credential, $domain);
public function getVersion()
{
return $this->version;
}
public function setVersion($version)
{
$this->version = $version;
}
public function getProduct()
{
return $this->product;
}
public function setProduct($product)
{
$this->product = $product;
}
public function getActionName()
{
return $this->actionName;
}
public function setActionName($actionName)
{
$this->actionName = $actionName;
}
public function getAcceptFormat()
{
return $this->acceptFormat;
}
public function setAcceptFormat($acceptFormat)
{
$this->acceptFormat = $acceptFormat;
}
public function getQueryParameters()
{
return $this->queryParameters;
}
public function getHeaders()
{
return $this->headers;
}
public function getMethod()
{
return $this->method;
}
public function setMethod($method)
{
$this->method = $method;
}
public function getProtocol()
{
return $this->protocolType;
}
public function setProtocol($protocol)
{
$this->protocolType = $protocol;
}
public function getRegionId()
{
return $this->regionId;
}
public function setRegionId($region)
{
$this->regionId = $region;
}
public function getContent()
{
return $this->content;
}
public function setContent($content)
{
$this->content = $content;
}
public function addHeader($headerKey, $headerValue)
{
$this->headers[$headerKey] = $headerValue;
}
}
\ No newline at end of file
<?php
namespace Aliyun\Core;
class AcsResponse
{
private $code;
private $message;
public function getCode()
{
return $this->code;
}
public function setCode($code)
{
$this->code = $code;
}
public function getMessage()
{
return $this->message;
}
public function setMessage($message)
{
$this->message = $message;
}
}
\ No newline at end of file
<?php
namespace Aliyun\Core\Auth;
class Credential
{
private $dateTimeFormat = 'Y-m-d\TH:i:s\Z';
private $refreshDate;
private $expiredDate;
private $accessKeyId;
private $accessSecret;
private $securityToken;
function __construct($accessKeyId, $accessSecret)
{
$this->accessKeyId = $accessKeyId;
$this->accessSecret = $accessSecret;
$this->refreshDate = date($this->dateTimeFormat);
}
public function isExpired()
{
if($this->expiredDate == null)
{
return false;
}
if(strtotime($this->expiredDate)>date($this->dateTimeFormat))
{
return false;
}
return true;
}
public function getRefreshDate()
{
return $this->refreshDate;
}
public function getExpiredDate()
{
return $this->expiredDate;
}
public function setExpiredDate($expiredHours)
{
if($expiredHours>0)
{
return $this->expiredDate = date($this->dateTimeFormat, strtotime("+".$expiredHours." hour"));
}
}
public function getAccessKeyId()
{
return $this->accessKeyId;
}
public function setAccessKeyId($accessKeyId)
{
$this->accessKeyId = $accessKeyId;
}
public function getAccessSecret()
{
return $this->accessSecret;
}
public function setAccessSecret($accessSecret)
{
$this->accessSecret = $accessSecret;
}
}
\ No newline at end of file
<?php
namespace Aliyun\Core\Auth;
interface ISigner
{
public function getSignatureMethod();
public function getSignatureVersion();
public function signString($source, $accessSecret);
}
\ No newline at end of file
<?php
namespace Aliyun\Core\Auth;
class ShaHmac1Signer implements ISigner
{
public function signString($source, $accessSecret)
{
return base64_encode(hash_hmac('sha1', $source, $accessSecret, true));
}
public function getSignatureMethod() {
return "HMAC-SHA1";
}
public function getSignatureVersion() {
return "1.0";
}
}
\ No newline at end of file
<?php
namespace Aliyun\Core\Auth;
class ShaHmac256Signer implements ISigner
{
public function signString($source, $accessSecret)
{
return base64_encode(hash_hmac('sha256', $source, $accessSecret, true));
}
public function getSignatureMethod() {
return "HMAC-SHA256";
}
public function getSignatureVersion() {
return "1.0";
}
}
\ No newline at end of file
<?php
namespace Aliyun\Core;
use Aliyun\Core\Regions\EndpointConfig;
//config http proxy
define('ENABLE_HTTP_PROXY', FALSE);
define('HTTP_PROXY_IP', '127.0.0.1');
define('HTTP_PROXY_PORT', '8888');
class Config
{
private static $loaded = false;
public static function load(){
if(self::$loaded) {
return;
}
EndpointConfig::load();
self::$loaded = true;
}
}
\ No newline at end of file
<?php
namespace Aliyun\Core;
use Aliyun\Core\Exception\ClientException;
use Aliyun\Core\Exception\ServerException;
use Aliyun\Core\Regions\EndpointProvider;
use Aliyun\Core\Http\HttpHelper;
class DefaultAcsClient implements IAcsClient
{
public $iClientProfile;
public $__urlTestFlag__;
function __construct($iClientProfile)
{
$this->iClientProfile = $iClientProfile;
$this->__urlTestFlag__ = false;
}
public function getAcsResponse($request, $iSigner = null, $credential = null, $autoRetry = true, $maxRetryNumber = 3)
{
$httpResponse = $this->doActionImpl($request, $iSigner, $credential, $autoRetry, $maxRetryNumber);
$respObject = $this->parseAcsResponse($httpResponse->getBody(), $request->getAcceptFormat());
if(false == $httpResponse->isSuccess())
{
$this->buildApiException($respObject, $httpResponse->getStatus());
}
return $respObject;
}
private function doActionImpl($request, $iSigner = null, $credential = null, $autoRetry = true, $maxRetryNumber = 3)
{
if(null == $this->iClientProfile && (null == $iSigner || null == $credential
|| null == $request->getRegionId() || null == $request->getAcceptFormat()))
{
throw new ClientException("No active profile found.", "SDK.InvalidProfile");
}
if(null == $iSigner)
{
$iSigner = $this->iClientProfile->getSigner();
}
if(null == $credential)
{
$credential = $this->iClientProfile->getCredential();
}
$request = $this->prepareRequest($request);
$domain = EndpointProvider::findProductDomain($request->getRegionId(), $request->getProduct());
if(null == $domain)
{
throw new ClientException("Can not find endpoint to access.", "SDK.InvalidRegionId");
}
$requestUrl = $request->composeUrl($iSigner, $credential, $domain);
if ($this->__urlTestFlag__) {
throw new ClientException($requestUrl, "URLTestFlagIsSet");
}
if(count($request->getDomainParameter())>0){
$httpResponse = HttpHelper::curl($requestUrl, $request->getMethod(), $request->getDomainParameter(), $request->getHeaders());
} else {
$httpResponse = HttpHelper::curl($requestUrl, $request->getMethod(), $request->getContent(), $request->getHeaders());
}
$retryTimes = 1;
while (500 <= $httpResponse->getStatus() && $autoRetry && $retryTimes < $maxRetryNumber) {
$requestUrl = $request->composeUrl($iSigner, $credential,$domain);
if(count($request->getDomainParameter())>0){
$httpResponse = HttpHelper::curl($requestUrl, $request->getMethod(), $request->getDomainParameter(), $request->getHeaders());
} else {
$httpResponse = HttpHelper::curl($requestUrl, $request->getMethod(), $request->getContent(), $request->getHeaders());
}
$retryTimes ++;
}
return $httpResponse;
}
public function doAction($request, $iSigner = null, $credential = null, $autoRetry = true, $maxRetryNumber = 3)
{
trigger_error("doAction() is deprecated. Please use getAcsResponse() instead.", E_USER_NOTICE);
return $this->doActionImpl($request, $iSigner, $credential, $autoRetry, $maxRetryNumber);
}
private function prepareRequest($request)
{
if(null == $request->getRegionId())
{
$request->setRegionId($this->iClientProfile->getRegionId());
}
if(null == $request->getAcceptFormat())
{
$request->setAcceptFormat($this->iClientProfile->getFormat());
}
if(null == $request->getMethod())
{
$request->setMethod("GET");
}
return $request;
}
private function buildApiException($respObject, $httpStatus)
{
throw new ServerException($respObject->Message, $respObject->Code, $httpStatus, $respObject->RequestId);
}
private function parseAcsResponse($body, $format)
{
if ("JSON" == $format)
{
$respObject = json_decode($body);
}
else if("XML" == $format)
{
$respObject = @simplexml_load_string($body);
}
else if("RAW" == $format)
{
$respObject = $body;
}
return $respObject;
}
}
<?php
namespace Aliyun\Core\Exception;
class ClientException extends \Exception
{
function __construct($errorMessage, $errorCode)
{
parent::__construct($errorMessage);
$this->errorMessage = $errorMessage;
$this->errorCode = $errorCode;
$this->setErrorType("Client");
}
private $errorCode;
private $errorMessage;
private $errorType;
public function getErrorCode()
{
return $this->errorCode;
}
public function setErrorCode($errorCode)
{
$this->errorCode = $errorCode;
}
public function getErrorMessage()
{
return $this->errorMessage;
}
public function setErrorMessage($errorMessage)
{
$this->errorMessage = $errorMessage;
}
public function getErrorType()
{
return $this->errorType;
}
public function setErrorType($errorType)
{
$this->errorType = $errorType;
}
}
<?php
namespace Aliyun\Core\Exception;
class ServerException extends ClientException
{
private $httpStatus;
private $requestId;
function __construct($errorMessage, $errorCode, $httpStatus, $requestId)
{
$messageStr = $errorCode . " " . $errorMessage . " HTTP Status: " . $httpStatus . " RequestID: " . $requestId;
parent::__construct($messageStr, $errorCode);
$this->setErrorMessage($errorMessage);
$this->setErrorType("Server");
$this->httpStatus = $httpStatus;
$this->requestId = $requestId;
}
public function getHttpStatus()
{
return $this->httpStatus;
}
public function getRequestId()
{
return $this->requestId;
}
}
<?php
namespace Aliyun\Core\Http;
use Aliyun\Core\Exception\ClientException;
class HttpHelper
{
public static $connectTimeout = 30;//30 second
public static $readTimeout = 80;//80 second
public static function curl($url, $httpMethod = "GET", $postFields = null,$headers = null)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $httpMethod);
if(ENABLE_HTTP_PROXY) {
curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_PROXY, HTTP_PROXY_IP);
curl_setopt($ch, CURLOPT_PROXYPORT, HTTP_PROXY_PORT);
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
}
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FAILONERROR, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, is_array($postFields) ? self::getPostHttpBody($postFields) : $postFields);
if (self::$readTimeout) {
curl_setopt($ch, CURLOPT_TIMEOUT, self::$readTimeout);
}
if (self::$connectTimeout) {
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, self::$connectTimeout);
}
//https request
if(strlen($url) > 5 && strtolower(substr($url,0,5)) == "https" ) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
}
if (is_array($headers) && 0 < count($headers))
{
$httpHeaders =self::getHttpHearders($headers);
curl_setopt($ch,CURLOPT_HTTPHEADER,$httpHeaders);
}
$httpResponse = new HttpResponse();
$httpResponse->setBody(curl_exec($ch));
$httpResponse->setStatus(curl_getinfo($ch, CURLINFO_HTTP_CODE));
if (curl_errno($ch))
{
throw new ClientException("Server unreachable: Errno: " . curl_errno($ch) . " " . curl_error($ch), "SDK.ServerUnreachable");
}
curl_close($ch);
return $httpResponse;
}
static function getPostHttpBody($postFildes){
$content = "";
foreach ($postFildes as $apiParamKey => $apiParamValue)
{
$content .= "$apiParamKey=" . urlencode($apiParamValue) . "&";
}
return substr($content, 0, -1);
}
static function getHttpHearders($headers)
{
$httpHeader = array();
foreach ($headers as $key => $value)
{
array_push($httpHeader, $key.":".$value);
}
return $httpHeader;
}
}
<?php
namespace Aliyun\Core\Http;
class HttpResponse
{
private $body;
private $status;
public function getBody()
{
return $this->body;
}
public function setBody($body)
{
$this->body = $body;
}
public function getStatus()
{
return $this->status;
}
public function setStatus($status)
{
$this->status = $status;
}
public function isSuccess()
{
if(200 <= $this->status && 300 > $this->status)
{
return true;
}
return false;
}
}
\ No newline at end of file
<?php
namespace Aliyun\Core;
interface IAcsClient
{
public function doAction($requst);
}
\ No newline at end of file
<?php
namespace Aliyun\Core\Profile;
use Aliyun\Core\Auth\Credential;
use Aliyun\Core\Auth\ShaHmac1Signer;
use Aliyun\Core\Regions\ProductDomain;
use Aliyun\Core\Regions\Endpoint;
use Aliyun\Core\Regions\EndpointProvider;
class DefaultProfile implements IClientProfile
{
private static $profile;
private static $endpoints;
private static $credential;
private static $regionId;
private static $acceptFormat;
private static $isigner;
private static $iCredential;
private function __construct($regionId,$credential)
{
self::$regionId = $regionId;
self::$credential = $credential;
}
public static function getProfile($regionId, $accessKeyId, $accessSecret)
{
$credential =new Credential($accessKeyId, $accessSecret);
self::$profile = new DefaultProfile($regionId, $credential);
return self::$profile;
}
public function getSigner()
{
if(null == self::$isigner)
{
self::$isigner = new ShaHmac1Signer();
}
return self::$isigner;
}
public function getRegionId()
{
return self::$regionId;
}
public function getFormat()
{
return self::$acceptFormat;
}
public function getCredential()
{
if(null == self::$credential && null != self::$iCredential)
{
self::$credential = self::$iCredential;
}
return self::$credential;
}
public static function getEndpoints()
{
if(null == self::$endpoints)
{
self::$endpoints = EndpointProvider::getEndpoints();
}
return self::$endpoints;
}
public static function addEndpoint($endpointName, $regionId, $product, $domain)
{
if(null == self::$endpoints)
{
self::$endpoints = self::getEndpoints();
}
$endpoint = self::findEndpointByName($endpointName);
if(null == $endpoint)
{
self::addEndpoint_($endpointName, $regionId, $product, $domain);
}
else
{
self::updateEndpoint($regionId, $product, $domain, $endpoint);
}
}
public static function findEndpointByName($endpointName)
{
foreach (self::$endpoints as $key => $endpoint)
{
if($endpoint->getName() == $endpointName)
{
return $endpoint;
}
}
}
private static function addEndpoint_($endpointName,$regionId, $product, $domain)
{
$regionIds = array($regionId);
$productDomains = array(new ProductDomain($product, $domain));
$endpoint = new Endpoint($endpointName, $regionIds, $productDomains);
array_push(self::$endpoints, $endpoint);
}
private static function updateEndpoint($regionId, $product, $domain, $endpoint)
{
$regionIds = $endpoint->getRegionIds();
if(!in_array($regionId,$regionIds))
{
array_push($regionIds, $regionId);
$endpoint->setRegionIds($regionIds);
}
$productDomains = $endpoint->getProductDomains();
if(null == self::findProductDomain($productDomains, $product, $domain))
{
array_push($productDomains, new ProductDomain($product, $domain));
}
$endpoint->setProductDomains($productDomains);
}
private static function findProductDomain($productDomains, $product, $domain)
{
foreach ($productDomains as $key => $productDomain)
{
if($productDomain->getProductName() == $product && $productDomain->getDomainName() == $domain)
{
return $productDomain;
}
}
return null;
}
}
\ No newline at end of file
<?php
namespace Aliyun\Core\Profile;
interface IClientProfile
{
public function getSigner();
public function getRegionId();
public function getFormat();
public function getCredential();
}
\ No newline at end of file
<?php
namespace Aliyun\Core\Regions;
class Endpoint
{
private $name;
private $regionIds;
private $productDomains;
function __construct($name, $regionIds, $productDomains)
{
$this->name = $name;
$this->regionIds = $regionIds;
$this->productDomains = $productDomains;
}
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
}
public function getRegionIds()
{
return $this->regionIds;
}
public function setRegionIds($regionIds)
{
$this->regionIds = $regionIds;
}
public function getProductDomains()
{
return $this->productDomains;
}
public function setProductDomains($productDomains)
{
$this->productDomains = $productDomains;
}
}
\ No newline at end of file
<?php
namespace Aliyun\Core\Regions;
class EndpointConfig {
private static $loaded = false;
public static function load() {
if(self::$loaded) {
return;
}
$endpoint_filename = dirname(__FILE__) . DIRECTORY_SEPARATOR . "endpoints.xml";
$xml = simplexml_load_string(file_get_contents($endpoint_filename));
$json = json_encode($xml);
$json_array = json_decode($json, TRUE);
$endpoints = array();
foreach ($json_array["Endpoint"] as $json_endpoint) {
# pre-process RegionId & Product
if (!array_key_exists("RegionId", $json_endpoint["RegionIds"])) {
$region_ids = array();
} else {
$json_region_ids = $json_endpoint['RegionIds']['RegionId'];
if (!is_array($json_region_ids)) {
$region_ids = array($json_region_ids);
} else {
$region_ids = $json_region_ids;
}
}
if (!array_key_exists("Product", $json_endpoint["Products"])) {
$products = array();
} else {
$json_products = $json_endpoint["Products"]["Product"];
if (array() === $json_products or !is_array($json_products)) {
$products = array();
} else if (array_keys($json_products) !== range(0, count($json_products) - 1)) {
# array is not sequential
$products = array($json_products);
} else {
$products = $json_products;
}
}
$product_domains = array();
foreach ($products as $product) {
$product_domain = new ProductDomain($product['ProductName'], $product['DomainName']);
array_push($product_domains, $product_domain);
}
$endpoint = new Endpoint($region_ids[0], $region_ids, $product_domains);
array_push($endpoints, $endpoint);
}
EndpointProvider::setEndpoints($endpoints);
self::$loaded = true;
}
}
<?php
namespace Aliyun\Core\Regions;
class EndpointProvider
{
private static $endpoints;
public static function findProductDomain($regionId, $product)
{
if(null == $regionId || null == $product || null == self::$endpoints)
{
return null;
}
foreach (self::$endpoints as $key => $endpoint)
{
if(in_array($regionId, $endpoint->getRegionIds()))
{
return self::findProductDomainByProduct($endpoint->getProductDomains(), $product);
}
}
return null;
}
private static function findProductDomainByProduct($productDomains, $product)
{
if(null == $productDomains)
{
return null;
}
foreach ($productDomains as $key => $productDomain)
{
if($product == $productDomain->getProductName())
{
return $productDomain->getDomainName();
}
}
return null;
}
public static function getEndpoints()
{
return self::$endpoints;
}
public static function setEndpoints($endpoints)
{
self::$endpoints = $endpoints;
}
}
\ No newline at end of file
<?php
namespace Aliyun\Core\Regions;
class ProductDomain
{
private $productName;
private $domainName;
function __construct($product, $domain) {
$this->productName = $product;
$this->domainName = $domain;
}
public function getProductName() {
return $this->productName;
}
public function setProductName($productName) {
$this->productName = $productName;
}
public function getDomainName() {
return $this->domainName;
}
public function setDomainName($domainName) {
$this->domainName = $domainName;
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
<?php
namespace Aliyun\Core;
abstract class RoaAcsRequest extends AcsRequest
{
protected $uriPattern;
private $pathParameters = array();
private $domainParameters = array();
private $dateTimeFormat ="D, d M Y H:i:s \G\M\T";
private static $headerSeparator = "\n";
private static $querySeprator = "&";
function __construct($product, $version, $actionName)
{
parent::__construct($product, $version, $actionName);
$this->setVersion($version);
$this->initialize();
}
private function initialize()
{
$this->setMethod("RAW");
}
public function composeUrl($iSigner, $credential, $domain)
{
$this->prepareHeader($iSigner);
$signString = $this->getMethod().self::$headerSeparator;
if(isset($this->headers["Accept"]))
{
$signString = $signString.$this->headers["Accept"];
}
$signString = $signString.self::$headerSeparator;
if(isset($this->headers["Content-MD5"]))
{
$signString = $signString.$this->headers["Content-MD5"];
}
$signString = $signString.self::$headerSeparator;
if(isset($this->headers["Content-Type"]))
{
$signString = $signString.$this->headers["Content-Type"];
}
$signString = $signString.self::$headerSeparator;
if(isset($this->headers["Date"]))
{
$signString = $signString.$this->headers["Date"];
}
$signString = $signString.self::$headerSeparator;
$uri = $this->replaceOccupiedParameters();
$signString = $signString.$this->buildCanonicalHeaders();
$queryString = $this->buildQueryString($uri);
$signString .= $queryString;
$this->headers["Authorization"] = "acs ".$credential->getAccessKeyId().":"
.$iSigner->signString($signString, $credential->getAccessSecret());
$requestUrl = $this->getProtocol()."://".$domain.$queryString;
return $requestUrl;
}
private function prepareHeader($iSigner)
{
$this->headers["Date"] = gmdate($this->dateTimeFormat);
if(null == $this->acceptFormat)
{
$this->acceptFormat = "RAW";
}
$this->headers["Accept"] = $this->formatToAccept($this->getAcceptFormat());
$this->headers["x-acs-signature-method"] = $iSigner->getSignatureMethod();
$this->headers["x-acs-signature-version"] = $iSigner->getSignatureVersion();
$this->headers["x-acs-region-id"] = $this->regionId;
$content = $this->getDomainParameter();
if ($content != null) {
$this->headers["Content-MD5"] = base64_encode(md5(json_encode($content),true));
}
$this->headers["Content-Type"] = "application/octet-stream;charset=utf-8";
}
private function replaceOccupiedParameters()
{
$result = $this->uriPattern;
foreach ($this->pathParameters as $pathParameterKey => $apiParameterValue)
{
$target = "[".$pathParameterKey."]";
$result = str_replace($target,$apiParameterValue,$result);
}
return $result;
}
private function buildCanonicalHeaders()
{
$sortMap = array();
foreach ($this->headers as $headerKey => $headerValue)
{
$key = strtolower($headerKey);
if(strpos($key, "x-acs-") === 0)
{
$sortMap[$key] = $headerValue;
}
}
ksort($sortMap);
$headerString = "";
foreach ($sortMap as $sortMapKey => $sortMapValue)
{
$headerString = $headerString.$sortMapKey.":".$sortMapValue.self::$headerSeparator;
}
return $headerString;
}
private function splitSubResource($uri)
{
$queIndex = strpos($uri, "?");
$uriParts = array();
if(null != $queIndex)
{
array_push($uriParts, substr($uri,0,$queIndex));
array_push($uriParts, substr($uri,$queIndex+1));
}
else
{
array_push($uriParts,$uri);
}
return $uriParts;
}
private function buildQueryString($uri)
{
$uriParts = $this->splitSubResource($uri);
$sortMap = $this->queryParameters;
if(isset($uriParts[1]))
{
$sortMap[$uriParts[1]] = null;
}
$queryString = $uriParts[0];
if(count($uriParts))
{
$queryString = $queryString."?";
}
ksort($sortMap);
foreach ($sortMap as $sortMapKey => $sortMapValue)
{
$queryString = $queryString.$sortMapKey;
if(isset($sortMapValue))
{
$queryString = $queryString."=".$sortMapValue;
}
$queryString = $queryString.$querySeprator;
}
if(null==count($sortMap))
{
$queryString = substr($queryString, 0, strlen($queryString)-1);
}
return $queryString;
}
private function formatToAccept($acceptFormat)
{
if($acceptFormat == "JSON")
{
return "application/json";
}
elseif ($acceptFormat == "XML") {
return "application/xml";
}
return "application/octet-stream";
}
public function getPathParameters()
{
return $this->pathParameters;
}
public function putPathParameter($name, $value)
{
$this->pathParameters[$name] = $value;
}
public function getDomainParameter()
{
return $this->domainParameters;
}
public function putDomainParameters($name, $value)
{
$this->domainParameters[$name] = $value;
}
public function getUriPattern()
{
return $this->uriPattern;
}
public function setUriPattern($uriPattern)
{
return $this->uriPattern = $uriPattern;
}
public function setVersion($version)
{
$this->version = $version;
$this->headers["x-acs-version"] = $version;
}
}
\ No newline at end of file
<?php
namespace Aliyun\Core;
abstract class RpcAcsRequest extends AcsRequest
{
private $dateTimeFormat = 'Y-m-d\TH:i:s\Z';
private $domainParameters = array();
function __construct($product, $version, $actionName)
{
parent::__construct($product, $version, $actionName);
$this->initialize();
}
private function initialize()
{
$this->setMethod("GET");
$this->setAcceptFormat("JSON");
}
private function prepareValue($value)
{
if (is_bool($value)) {
if ($value) {
return "true";
} else {
return "false";
}
} else {
return $value;
}
}
public function composeUrl($iSigner, $credential, $domain)
{
$apiParams = parent::getQueryParameters();
foreach ($apiParams as $key => $value) {
$apiParams[$key] = $this->prepareValue($value);
}
$apiParams["RegionId"] = $this->getRegionId();
$apiParams["AccessKeyId"] = $credential->getAccessKeyId();
$apiParams["Format"] = $this->getAcceptFormat();
$apiParams["SignatureMethod"] = $iSigner->getSignatureMethod();
$apiParams["SignatureVersion"] = $iSigner->getSignatureVersion();
$apiParams["SignatureNonce"] = md5(uniqid(mt_rand(), true));
$apiParams["Timestamp"] = gmdate($this->dateTimeFormat);
$apiParams["Action"] = $this->getActionName();
$apiParams["Version"] = $this->getVersion();
$apiParams["Signature"] = $this->computeSignature($apiParams, $credential->getAccessSecret(), $iSigner);
if(parent::getMethod() == "POST") {
$requestUrl = $this->getProtocol()."://". $domain . "/";
foreach ($apiParams as $apiParamKey => $apiParamValue)
{
$this->putDomainParameters($apiParamKey,$apiParamValue);
}
return $requestUrl;
}
else {
$requestUrl = $this->getProtocol()."://". $domain . "/?";
foreach ($apiParams as $apiParamKey => $apiParamValue)
{
$requestUrl .= "$apiParamKey=" . urlencode($apiParamValue) . "&";
}
return substr($requestUrl, 0, -1);
}
}
private function computeSignature($parameters, $accessKeySecret, $iSigner)
{
ksort($parameters);
$canonicalizedQueryString = '';
foreach($parameters as $key => $value)
{
$canonicalizedQueryString .= '&' . $this->percentEncode($key). '=' . $this->percentEncode($value);
}
$stringToSign = parent::getMethod().'&%2F&' . $this->percentencode(substr($canonicalizedQueryString, 1));
$signature = $iSigner->signString($stringToSign, $accessKeySecret."&");
return $signature;
}
protected function percentEncode($str)
{
$res = urlencode($str);
$res = preg_replace('/\+/', '%20', $res);
$res = preg_replace('/\*/', '%2A', $res);
$res = preg_replace('/%7E/', '~', $res);
return $res;
}
public function getDomainParameter()
{
return $this->domainParameters;
}
public function putDomainParameters($name, $value)
{
$this->domainParameters[$name] = $value;
}
}
<?php
// autoload.php @generated by Composer
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInitee70723fd3132b6d05f0ff016c58b71b::getLoader();
This diff is collapsed.
Copyright (c) Nils Adermann, Jordi Boggiano
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
<?php
// autoload_classmap.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
);
<?php
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
);
<?php
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'Aliyun\\' => array($baseDir . '/lib'),
);
<?php
// autoload_real.php @generated by Composer
class ComposerAutoloaderInitee70723fd3132b6d05f0ff016c58b71b
{
private static $loader;
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInitee70723fd3132b6d05f0ff016c58b71b', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInitee70723fd3132b6d05f0ff016c58b71b', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) {
require_once __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInitee70723fd3132b6d05f0ff016c58b71b::getInitializer($loader));
} else {
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);
}
$map = require __DIR__ . '/autoload_psr4.php';
foreach ($map as $namespace => $path) {
$loader->setPsr4($namespace, $path);
}
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
}
$loader->register(true);
return $loader;
}
}
<?php
// autoload_static.php @generated by Composer
namespace Composer\Autoload;
class ComposerStaticInitee70723fd3132b6d05f0ff016c58b71b
{
public static $prefixLengthsPsr4 = array (
'A' =>
array (
'Aliyun\\' => 7,
),
);
public static $prefixDirsPsr4 = array (
'Aliyun\\' =>
array (
0 => __DIR__ . '/../..' . '/lib',
),
);
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInitee70723fd3132b6d05f0ff016c58b71b::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitee70723fd3132b6d05f0ff016c58b71b::$prefixDirsPsr4;
}, null, ClassLoader::class);
}
}
......@@ -22,14 +22,17 @@
"php": "^7.2",
"emadadly/laravel-uuid": "^1.3",
"fideloper/proxy": "^4.0",
"ibrand/laravel-sms": "~1.0",
"influxdb/influxdb-php": "^1.15",
"laravel/framework": "^7.0",
"laravel/passport": "^8.4",
"laravel/tinker": "^2.0",
"league/flysystem-aws-s3-v3": "^1.0",
"mrgoon/aliyun-sms": "dev-master",
"predis/predis": "^1.1",
"spatie/laravel-permission": "^3.0",
"swooletw/laravel-swoole": "^2.6",
"toplan/laravel-sms": "~2.6",
"try-to/swoole_mqtt": "^0.0.5"
},
"require-dev": {
......
This diff is collapsed.
......@@ -149,7 +149,7 @@ return [
Illuminate\Broadcasting\BroadcastServiceProvider::class,
Illuminate\Bus\BusServiceProvider::class,
Illuminate\Cache\CacheServiceProvider::class,
Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
IlluminatPhpSmsServiceProvidere\Foundation\Providers\ConsoleSupportServiceProvider::class,
Illuminate\Cookie\CookieServiceProvider::class,
Illuminate\Database\DatabaseServiceProvider::class,
Illuminate\Encryption\EncryptionServiceProvider::class,
......@@ -167,7 +167,6 @@ return [
Illuminate\Translation\TranslationServiceProvider::class,
Illuminate\Validation\ValidationServiceProvider::class,
Illuminate\View\ViewServiceProvider::class,
/*
* Package Service Providers...
*/
......@@ -230,7 +229,6 @@ return [
'URL' => Illuminate\Support\Facades\URL::class,
'Validator' => Illuminate\Support\Facades\Validator::class,
'View' => Illuminate\Support\Facades\View::class,
],
];
<?php
return [
/*
|--------------------------------------------------------------------------
| 内置路由
|--------------------------------------------------------------------------
|
| 如果是 web 应用建议 middleware 为 ['web', ...]
| 如果是 api 应用建议 middleware 为 ['api', ...]
|
*/
'route' => [
'enable' => true,
'prefix' => 'laravel-sms',
'middleware' => ['web'],
],
/*
|--------------------------------------------------------------------------
| 请求间隔
|--------------------------------------------------------------------------
|
| 单位:秒
|
*/
'interval' => 60,
/*
|--------------------------------------------------------------------------
| 数据验证管理
|--------------------------------------------------------------------------
|
| 设置从客户端传来的需要验证的数据字段(`field`)
|
| - isMobile 是否为手机号字段
| - enable 是否开启验证
| - default 默认静态验证规则
| - staticRules 静态验证规则
|
*/
'validation' => [
'mobile' => [
'isMobile' => true,
'enable' => true,
'default' => 'mobile_required',
'staticRules' => [
'mobile_required' => 'required|zh_mobile',
'check_mobile_unique' => 'required|zh_mobile|unique:users,mobile',
'check_mobile_exists' => 'required|zh_mobile|exists:users',
],
],
],
/*
|--------------------------------------------------------------------------
| 验证码管理
|--------------------------------------------------------------------------
|
| - length 验证码长度
| - validMinutes 验证码有效时间长度,单位为分钟
| - repeatIfValid 如果原验证码还有效,是否重复使用原验证码
| - maxAttempts 验证码最大尝试验证次数,超过该数值验证码自动失效,0或负数则不启用
|
*/
'code' => [
'length' => 5,
'validMinutes' => 5,
'repeatIfValid' => false,
'maxAttempts' => 0,
],
/*
|--------------------------------------------------------------------------
| 验证码短信通用内容
|--------------------------------------------------------------------------
|
| 如需缓存配置,则需使用 `Toplan\Sms\SmsManger::closure($closure)` 方法进行配置
|
*/
'content' => function ($code, $minutes, $input) {
return '【signature】您的验证码是' . $code . ',有效期为' . $minutes . '分钟,请尽快验证。';
},
/*
|--------------------------------------------------------------------------
| 验证码短信模版
|--------------------------------------------------------------------------
|
| 每项数据的值可以为以下三种之一:
|
| - 字符串/数字
| 如: 'YunTongXun' => '短信模版id'
|
| - 数组
| 如: 'Alidayu' => ['短信模版id', '语音模版id'],
|
| - 匿名函数
| 如: 'YunTongXun' => function ($input, $type) {
| return $input['isRegister'] ? 'registerTempId' : 'commonId';
| }
|
| 如需缓存配置,则需使用 `Toplan\Sms\SmsManger::closure($closure)` 方法对匿名函数进行配置
|
*/
'templates' => [
'Aliyun' => 'SMS_169897307'
],
/*
|--------------------------------------------------------------------------
| 模版数据管理
|--------------------------------------------------------------------------
|
| 每项数据的值可以为以下两种之一:
|
| - 基本数据类型
| 如: 'minutes' => 5
|
| - 匿名函数(如果该函数不返回任何值,即表示不使用该项数据)
| 如: 'serialNumber' => function ($code, $minutes, $input, $type) {
| return $input['serialNumber'];
| }
| 如: 'hello' => function ($code, $minutes, $input, $type) {
| //不返回任何值,那么hello将会从模版数据中移除 :)
| }
|
| 如需缓存配置,则需使用 `Toplan\Sms\SmsManger::closure($closure)` 方法对匿名函数进行配置
|
*/
'data' => [
'code' => function ($code) {
return $code;
},
'minutes' => function ($code, $minutes) {
return $minutes;
},
],
/*
|--------------------------------------------------------------------------
| 存储系统配置
|--------------------------------------------------------------------------
|
| driver:
| 存储方式,是一个实现了'Toplan\Sms\Storage'接口的类的类名,
| 内置可选的值有'Toplan\Sms\SessionStorage'和'Toplan\Sms\CacheStorage',
| 如果不填写driver,那么系统会自动根据内置路由的属性(route)中middleware的配置值选择存储器driver:
| - 如果中间件含有'web',会选择使用'Toplan\Sms\SessionStorage'
| - 如果中间件含有'api',会选择使用'Toplan\Sms\CacheStorage'
|
| prefix:
| 存储key的prefix
|
| 内置driver的个性化配置:
| - 在laravel项目的'config/session.php'文件中可以对'Toplan\Sms\SessionStorage'进行更多个性化设置
| - 在laravel项目的'config/cache.php'文件中可以对'Toplan\Sms\CacheStorage'进行更多个性化设置
|
*/
'storage' => [
'driver' => '',
'prefix' => 'laravel_sms',
],
/*
|--------------------------------------------------------------------------
| 是否数据库记录发送日志
|--------------------------------------------------------------------------
|
| 若需开启此功能,需要先生成一个内置的'laravel_sms'表
| 运行'php artisan migrate'命令可以自动生成
|
*/
'dbLogs' => false,
/*
|--------------------------------------------------------------------------
| 队列任务
|--------------------------------------------------------------------------
|
*/
'queueJob' => 'Toplan\Sms\SendReminderSms',
/*
|--------------------------------------------------------------------------
| 验证码模块提示信息
|--------------------------------------------------------------------------
|
*/
'notifies' => [
// 频繁请求无效的提示
'request_invalid' => '请求无效,请在%s秒后重试',
// 验证码短信发送失败的提示
'sms_sent_failure' => '短信验证码发送失败,请稍后重试',
// 语音验证码发送发送成功的提示
'voice_sent_failure' => '语音验证码请求失败,请稍后重试',
// 验证码短信发送成功的提示
'sms_sent_success' => '短信验证码发送成功,请注意查收',
// 语音验证码发送发送成功的提示
'voice_sent_success' => '语音验证码发送成功,请注意接听',
],
];
<?php
return [
/*
* The scheme information
* -------------------------------------------------------------------
*
* The key-value paris: {name} => {value}
*
* Examples:
* 'Log' => '10 backup'
* 'SmsBao' => '100'
* 'CustomAgent' => [
* '5 backup',
* 'agentClass' => '/Namespace/ClassName'
* ]
*
* Supported agents:
* 'Log', 'YunPian', 'YunTongXun', 'SubMail', 'Luosimao',
* 'Ucpaas', 'JuHe', 'Alidayu', 'SendCloud', 'SmsBao',
* 'Qcloud', 'Aliyun'
*
*/
'scheme' => [
'Log',
'Aliyun' => '100'
],
/*
* The configuration
* -------------------------------------------------------------------
*
* Expected the name of agent to be a string.
*
*/
'agents' => [
/*
* -----------------------------------
* YunPian
* 云片代理器
* -----------------------------------
* website:http://www.yunpian.com
* support content sms.
*/
'YunPian' => [
//用户唯一标识,必须
'apikey' => 'your_api_key',
],
/*
* -----------------------------------
* YunTongXun
* 云通讯代理器
* -----------------------------------
* website:http://www.yuntongxun.com/
* support template sms.
*/
'YunTongXun' => [
//主帐号
'accountSid' => 'your_account_sid',
//主帐号令牌
'accountToken' => 'your_account_token',
//应用Id
'appId' => 'your_app_id',
//请求地址(不加协议前缀)
'serverIP' => 'app.cloopen.com',
//请求端口
'serverPort' => '8883',
//被叫号显
'displayNum' => null,
//语音验证码播放次数
'playTimes' => 3,
],
/*
* -----------------------------------
* SubMail
* -----------------------------------
* website:http://submail.cn/
* support template sms.
*/
'SubMail' => [
'appid' => 'your_app_id',
'signature' => 'your app key',
],
/*
* -----------------------------------
* luosimao
* -----------------------------------
* website:http://luosimao.com
* support content sms.
*/
'Luosimao' => [
'apikey' => 'your_api_key',
'voiceApikey' => 'your_voice_api_key',
],
/*
* -----------------------------------
* ucpaas
* -----------------------------------
* website:http://ucpaas.com
* support template sms.
*/
'Ucpaas' => [
//主帐号,对应开官网发者主账号下的 ACCOUNT SID
'accountSid' => 'your_account_sid',
//主帐号令牌,对应官网开发者主账号下的 AUTH TOKEN
'accountToken' => 'your_account_token',
//应用Id,在官网应用列表中点击应用,对应应用详情中的APP ID
//在开发调试的时候,可以使用官网自动为您分配的测试Demo的APP ID
'appId' => 'your_app_id',
],
/*
* -----------------------------------
* JuHe
* 聚合数据
* -----------------------------------
* website:https://www.juhe.cn
* support template sms.
*/
'JuHe' => [
//应用App Key
'key' => 'your_key',
//语音验证码播放次数
'times' => 3,
],
/*
* -----------------------------------
* Alidayu
* 阿里大鱼代理器
* -----------------------------------
* website:http://www.alidayu.com
* support template sms.
*/
'Alidayu' => [
//请求地址
'sendUrl' => 'http://gw.api.taobao.com/router/rest',
//淘宝开放平台中,对应阿里大鱼短信应用的App Key
'appKey' => 'your_app_key',
//淘宝开放平台中,对应阿里大鱼短信应用的App Secret
'secretKey' => 'your_secret_key',
//短信签名,传入的短信签名必须是在阿里大鱼“管理中心-短信签名管理”中的可用签名
'smsFreeSignName' => 'your_sms_free_sign_name',
//被叫号显(用于语音通知),传入的显示号码必须是阿里大鱼“管理中心-号码管理”中申请或购买的号码
'calledShowNum' => null,
],
/*
* -----------------------------------
* SendCloud
* -----------------------------------
* website: http://sendcloud.sohu.com/sms/
* support template sms.
*/
'SendCloud' => [
'smsUser' => 'your_SMS_USER',
'smsKey' => 'your_SMS_KEY',
],
/*
* -----------------------------------
* SmsBao
* -----------------------------------
* website: http://www.smsbao.com
* support content sms.
*/
'SmsBao' => [
//注册账号
'username' => 'your_username',
//账号密码(明文)
'password' => 'your_password',
],
/*
* -----------------------------------
* Qcloud
* 腾讯云
* -----------------------------------
* website:http://www.qcloud.com
* support template sms.
*/
'Qcloud' => [
'appId' => 'your_app_id',
'appKey' => 'your_app_key',
],
/*
* -----------------------------------
* Aliyun
* 阿里云
* -----------------------------------
* website:https://www.aliyun.com/product/sms
* support template sms.
*/
'Aliyun' => [
'accessKeyId' => 'LTAI2xiZNF3iV2aV',
'accessKeySecret' => 'bprEWwn1M0xgglRQCQEMYSPiYctDk4',
'signName' => '泽宏云',
'regionId' => 'cn-beijing',
],
],
];
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment