可能是目前最靠谱、优雅的php短信发送库了。
phpsms的任务负载均衡功能由task-balancer提供。
- 支持短信/语音发送均衡调度,可按代理器权重值均衡选择服务商发送。
- 支持一个或多个备用代理器(服务商)。
- 允许推入队列,并自定义队列实现逻辑(与队列系统松散耦合)。
- 支持语音验证码。
- 短信/语音验证码发送前后钩子。
- 支持国内主流短信服务商。
- 自定义代理器和性感的寄生代理器。
服务商 | 模板短信 | 内容短信 | 语音验证码 | 最低消费 | 最低消费单价 |
---|---|---|---|---|---|
Luosimao | × | √ | √ | ¥850(1万条) | ¥0.085/条 |
云片网络 | × | √ | √ | ¥55(1千条) | ¥0.055/条 |
容联·云通讯 | √ | × | √ | 充值¥500 | ¥0.055/条 |
SUBMAIL | √ | × | × | ¥100(1千条) | ¥0.100/条 |
云之讯 | √ | × | √ | -- | ¥0.050/条 |
聚合数据 | √ | × | √ | -- | ¥0.035/条 |
composer require 'toplan/phpsms:~1.2.0'
###1. 配置
-
配置可用代理器
在
config\phpsms.php
中键为enable
的数组中配置。也可以手动在程序中设置:
//example:
Sms::enable([
//被使用概率为2/3
'Luosimao' => '20',
//被使用概率为1/3,且为备用代理器
'YunPian' => '10 backup',
//仅为备用代理器
'YunTongXun' => '0 backup',
]);
调度方案解析: 如果按照以上配置,那么系统首次会尝试使用
Luosimao
或YunPian
发送短信,且它们被使用的概率分别为2/3
和1/3
。 如果使用其中一个代理器发送失败,那么会启用备用代理器,按照配置可知备用代理器有YunPian
和YunTongXun
,那么会依次调用直到发送成功或无备用代理器可用。 值得注意的是,如果首次尝试的是YunPian
,那么备用代理器将会只使用YunTongXun
,也就是会排除使用过的代理器。
-
配置代理器所需参数
在
config\phpsms.php
中键为agents
的数组中配置。也可以手动在程序中设置:
//example:
Sms::agents([
'Luosimao' => [
//some options
],
'YunPian' => [
'apikey' => '...',
]
]);
###2. Enjoy it!
require('path/to/vendor/autoload.php');
use Toplan\PhpSms\Sms;
// 只希望使用模板方式发送短信,可以不设置content。
// 如:云通讯、Submail、Ucpaas
Sms::make()->to('1828****349')->template($templates)->data(['12345', 5])->send();
// 只希望使用内容方式放送,可以不设置模板id和模板数据data。
// 如:云片、luosimao
Sms::make()->to('1828****349')->content('【PhpSMS】亲爱的张三,欢迎访问,祝你工作愉快。')->send();
// 同时确保能通过模板和内容方式发送。
// 这样做的好处是,可以兼顾到各种类型服务商。
Sms::make()->to('1828****349')
->template([
'YunTongXun' => '123',
'SubMail' => '123'
])
->data(['张三'])
->content('【签名】亲爱的张三,欢迎访问,祝你工作愉快。')
->send();
//语言验证码
Sms::voice('1111')->to('1828****349')->send();
###3. 在laravel中使用
如果你只想单纯的在laravel中使用phpsms的功能可以按如下步骤操作, 当然也为你准备了基于phpsms开发的增强版laravel-sms
- 在config/app.php中引入服务提供器
//服务提供器
'providers' => [
...
Toplan\PhpSms\PhpSmsServiceProvide::class,
]
//别名
'aliases' => [
...
'PhpSms' => Toplan\PhpSms\Facades\Sms::class,
]
- 生成配置文件
php artisan vendor:publish
生成的配置文件为config/phpsms.php,然后在该文件中按提示配置。
- 使用
详见API,示例:
PhpSms::make()->to($to)->content($content)->send();
手动设置可用代理器及其调度方案(优先级高于配置文件),如:
Sms::enable([
'Luosimao' => '80 backup'
'YunPian' => '100 backup'
]);
//或
Sms::enable('Luosimao', '80 backup');
Sms::enable('YunPian', '100 backup');
enable
静态方法的更多使用方法见高级配置
手动设置代理器配置参数(优先级高于配置文件),如:
Sms::agents([
'YunPian' => [
'apikey' => '',
]
]);
//或
Sms::agents('YunPian', [
'apikey' => '',
]);
短信发送前钩子。
Sms::beforeSend(function($task, $prev, $index, $handlers){
//获取短信数据
$smsData = $task->data;
//do something here
});
更多细节请查看task-balancer的“beforeRun”钩子
短信发送后钩子。
Sms::afterSend(function($task, $result, $prev, $index, $handlers){
//$results为短信发送后获得的结果数组
//do something here
});
更多细节请查看task-balancer的“afterRun”钩子
设置是否启用队列以及定义如何推送到队列。
$handler可使用的参数:
$sms
: Sms实例。$data
: Sms实例中的短信数据,等同于$sms->getData()
。
定义如何推送到队列:
Sms::queue(function($sms, $data){
//define how to push to queue.
});//自动启用队列
//or
Sms::queue(true, function($sms, $data){
//define how to push to queue.
});//第一个参数为true,启用队列。
//or
Sms::queue(false, function($sms, $data){
//define how to push to queue.
});//第一个参数为false,暂时关闭队列。
如果已经定义过如何推送到队列,还可以继续设置关闭/开启队列:
Sms::queue(true);//开启队列
Sms::queue(false);//关闭队列
获取队列启用情况:
$enable = Sms::queue();
//为true,表示当前启用了队列。
//为false,表示当前关闭了队列。
生成发送短信的sms实例,并返回该实例。
$sms = Sms::make();
生成发送语音验证码的sms实例,并返回该实例。
$sms = Sms::voice($code)
设置发送给谁,并返回实例。
$sms->to('1828*******');
指定代理器进行设置或批量设置:
//静态方法设置,并返回sms实例
Sms::make(['YunTongXun' => '20001', 'SubMail' => 'xxx', ...]);
//设置指定服务商的模板id
$sms->template('YunTongXun', '20001')->template('SubMail', 'xxx');
//一次性设置多个服务商的模板id
$sms->template(['YunTongXun' => '20001', 'SubMail' => 'xxx', ...]);
设置模板短信的模板数据,并返回实例对象,$templateData
必须为数组。
$sms = $sms->data([
'code' => $code,
'minutes' => $minutes
]);
设置内容短信的内容,并返回实例对象。 有些服务商(如YunPian,Luosimao)只支持内容短信(即直接发送短信内容),那么就需要为它们设置短信内容。
$sms = $sms->content('【签名】您的订单号是xxxx,祝你购物愉快。');
临时设置发送时使用的代理器(不会影响备用代理器的正常使用),$name
为代理器名称。
$sms = $sms->agent('Luosimao');
通过该方法设置的代理器将获得绝对优先权,但只对当前短信实例有效。
请求发送短信/语音验证码。
//会遵循是否使用队列:
$result = $sms->send();
//忽略是否使用队列:
$result = $sms->send(true);
$result
数据结构请参看task-balancer
配置项加入到config/phpsms.php中键为agents
的数组里:
//请注意命名规范,Foo为代理器(服务商)名称。
'Foo' => [
'apikey' => 'some info',
...
]
在agents目录下添加代理器类:
建议代理器类名为FooAgent
,建议命名空间为Toplan\PhpSms
,必须继承Agent
抽象类。
如果命名空间不为
Toplan\PhpSms
则需要指定代理器类,详见高级配置。 如果使用到其它api库,可以将api库放入lib文件夹中。
namespace Toplan\PhpSms;
class FooAgent extends Agent {
//override
//发送短信一级入口
public function sendSms($tempId, $to, Array $data, $content){
//在这个方法中调用二级入口
//根据你使用的服务商的接口选择调用哪个方式发送短信
$this->sendContentSms($to, $content);
$this->sendTemplateSms($tempId, $to, Array $data);
}
//override
//发送短信二级入口:发送内容短信
public function sendContentSms($to, $content)
{
//获取配置文件中的参数
$x = $this->apikey;
//在这里实现发送内容短信,即直接发送内容
...
//切记将发送结果存入到$this->result
$this->result('success', true);//是否发送成功
$this->result('info', $msg);//发送结果信息说明
$this->result('code', $code);//发送结果代码
}
//override
//发送短信二级入口:发送模板短信
public function sendTemplateSms($tempId, $to, Array $data)
{
//同上...
}
//override
//发送语音验证码入口
public function voiceVerify($to, $code)
{
//同上...
}
}
至此, 新加代理器成功!
如果你自定义了一个代理器,但不是在Toplan\PhpSms
命名空间下,那么你还可以在调度配置时指定代理器使用的类。
Sms::enable([
'TestAgent1' => [
'10 backup',
'agentClass' => 'Your\Namespace\YourAgent'
]
]);
如果你既不想使用已有代理器,也不想自己写自定义代理器,那么寄生代理器或许是个好的选择,无需定义代理器类, 只需在调度配置时定义好发送短信和语音验证码的方式即可。
Sms::enable([
'TestAgent2' => [
'20 backup',
'sendSms' => function($agent, $data)) {
//$data为数组,包含了发送短信的相关数据:
//'to', 'tempId', 'tempData', 'content'
$to = $data['to'];
//获取配置(如果设置了的话):
$key = $agent->key;
//$agent实例可用方法:
$agent->sockPost($url, $query);//fsockopen
$agent->curl($url, array $params = [], $isPost = false);//curl
//设置发送结果:
$agent->result('success', true);
$agent->result('info', 'some info');
$agent->result('code', 'your code');
},
'voiceVerify' => function($agent, $data) {
//发送语音验证码,同上
}
]
]);
Sms::agents([
'TestAgent2' => [
'key' => '...'
]
]);
- 可用代理器分组配置功能;短信发送时选择分组进行发送的功能。
hi, guys! 如果喜欢或者要收藏,欢迎star。如果要提供意见和bug,欢迎issue或提交pr。
MIT