PHPackages                             toplan/phpsms - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. toplan/phpsms

ActiveLibrary

toplan/phpsms
=============

Probably the most intelligent, elegant sms send library in php

1.8.3(8y ago)638115.9k↓100%130[12 issues](https://github.com/toplan/phpsms/issues)[3 PRs](https://github.com/toplan/phpsms/pulls)3MITPHPPHP &gt;=5.4.0

Since Nov 13Pushed 7y ago30 watchersCompare

[ Source](https://github.com/toplan/phpsms)[ Packagist](https://packagist.org/packages/toplan/phpsms)[ RSS](/packages/toplan-phpsms/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (3)Versions (33)Used By (3)

PhpSms
======

[](#phpsms)

[![StyleCI](https://camo.githubusercontent.com/18e70de913e6636588021797bcf1ee1a5309d45ff3571db3fbf9e394d50ef558/68747470733a2f2f7374796c6563692e696f2f7265706f732f34343534333539392f736869656c64)](https://styleci.io/repos/44543599)[![Build Status](https://camo.githubusercontent.com/ab3de5b18035bdb14c4c89671bae9af35eb8e3edcc2c47f353f1bab81acffb09/68747470733a2f2f7472617669732d63692e6f72672f746f706c616e2f706870736d732e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/toplan/phpsms)[![Code Coverage](https://camo.githubusercontent.com/d69cbb9a325b157ad5db53afba4dd4ebe177d6598f53f040d2f41a31f5dc231f/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f746f706c616e2f706870736d732f6261646765732f636f7665726167652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/toplan/phpsms/?branch=master)[![Latest Stable Version](https://camo.githubusercontent.com/2318cde22a76821295ff4b4cee04e515bf6e900eaa2d4fdf9d4e18c8e850b85e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f746f706c616e2f706870736d732e737667)](https://packagist.org/packages/toplan/phpsms)[![Total Downloads](https://camo.githubusercontent.com/816855c6a5ef7d8a142f6ec9b3f0e6b6c3aa56f907902c2f6d3f1bde3cc313c7/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f746f706c616e2f706870736d732e737667)](https://packagist.org/packages/toplan/phpsms)

可能是目前最聪明、优雅的 php 短信发送库了。

> phpsms的任务均衡调度功能由[toplan/task-balancer](https://github.com/toplan/task-balancer)提供。

特别感谢以下赞助者:

[![短信宝](https://camo.githubusercontent.com/aeb5b83ea4dce083f4a8f8a6e2ef2925a298ac03d18b47558191a6f86c15f0a8/687474703a2f2f746f706c616e2e6769746875622e696f2f696d672f736d7362616f2d6c6f676f2e706e67)](http://www.smsbao.com/)

特点
==

[](#特点)

- 支持内容短信，模版短信，语音验证码，内容语音，模版语音，语音文件。
- 支持发送均衡调度，可按代理器权重值均衡选择服务商发送。
- 支持一个或多个备用代理器(服务商)。
- 支持代理器调度方案热更新，可随时更新/删除/新加代理器。
- 允许推入队列，并自定义队列实现逻辑(与队列系统松散耦合)。
- 灵活的发送前后钩子。
- 内置国内主流服务商的代理器。
- [自定义代理器](#%E8%87%AA%E5%AE%9A%E4%B9%89%E4%BB%A3%E7%90%86%E5%99%A8)和[寄生代理器](#%E5%AF%84%E7%94%9F%E4%BB%A3%E7%90%86%E5%99%A8)。

服务商
===

[](#服务商)

服务商模板短信内容短信语音验证码最低消费最低消费单价资费标准[Luosimao](http://luosimao.com)×√√￥850(1万条)￥0.085/条[资费标准](https://luosimao.com/service/sms#sms-price)[云片网络](http://www.yunpian.com)×√√￥55(1千条)￥0.055/条[资费标准](http://www.yunpian.com/price.html)[容联·云通讯](http://www.yuntongxun.com)√×√充值￥500￥0.055/条[资费标准](http://www.yuntongxun.com/price/price_sms.html)[SUBMAIL](http://submail.cn)√×√￥100(1千条)￥0.100/条[资费标准](https://www.mysubmail.com/chs/store#/message)[云之讯](http://www.ucpaas.com/)√×√--￥0.050/条[资费标准](http://www.ucpaas.com/service/sms.html)[聚合数据](https://www.juhe.cn/)√×√--￥0.035/条[资费标准](https://www.juhe.cn/docs/api/id/54)[阿里大鱼](https://www.alidayu.com/)√×√--￥0.045/条[资费标准](https://www.alidayu.com/service/price)[SendCloud](https://sendcloud.sohu.com/)√×√--￥0.048/条[资费标准](https://sendcloud.sohu.com/price.html)[短信宝](http://www.smsbao.com/)×√√￥5(50条)￥0.040/条(100万条)[资费标准](http://www.smsbao.com/fee/)[腾讯云](https://www.qcloud.com/product/sms)√√√--￥0.045/条[资费标准](https://www.qcloud.com/product/sms#price)[阿里云](https://www.aliyun.com/product/sms)√××--￥0.045/条[资费标准](https://cn.aliyun.com/price/product#/mns/detail)安装
==

[](#安装)

```
composer require toplan/phpsms:~1.8
```

开发中版本

```
composer require toplan/phpsms:dev-master
```

快速上手
====

[](#快速上手)

### 1. 配置

[](#1-配置)

- 配置代理器所需参数

为你需要用到的短信服务商(即代理器)配置必要的参数。可以在`config\phpsms.php`中键为`agents`的数组中配置，也可以手动在程序中设置，示例如下：

```
//example:
Sms::config([
    'Luosimao' => [
        'apikey' => 'your api key',
        'voiceApikey' => 'your voice api key',
    ],
    'YunPian'  => [
        'apikey' => 'your api key',
    ],
    'SmsBao' => [
        'username' => 'your username',
        'password'  => 'your password'
    ]
]);
```

- 配置代理器调度方案

可在`config\phpsms.php`中键为`scheme`的数组中配置。也可以手动在程序中设置，示例如下：

```
//example:
Sms::scheme([
    //被使用概率为2/3
    'Luosimao' => '20',

    //被使用概率为1/3，且为备用代理器
    'YunPian' => '10 backup',

    //仅为备用代理器
    'SmsBao' => '0 backup',
]);
```

> **调度方案解析：**如果按照以上配置，那么系统首次会尝试使用`Luosimao`或`YunPian`发送短信，且它们被使用的概率分别为`2/3`和`1/3`。 如果使用其中一个代理器发送失败，那么会启用备用代理器，按照配置可知备用代理器有`YunPian`和`SmsBao`，那么会依次调用直到发送成功或无备用代理器可用。 值得注意的是，如果首次尝试的是`YunPian`，那么备用代理器将会只使用`SmsBao`，也就是会排除使用过的代理器。

### 2. Enjoy it!

[](#2-enjoy-it)

```
require('path/to/vendor/autoload.php');
use Toplan\PhpSms\Sms;

// 接收人手机号
$to = '1828****349';
// 短信模版
$templates = [
    'YunTongXun' => 'your_temp_id',
    'SubMail'    => 'your_temp_id'
];
// 模版数据
$tempData = [
    'code' => '87392',
    'minutes' => '5'
];
// 短信内容
$content = '【签名】这是短信内容...';

// 只希望使用模板方式发送短信，可以不设置content(如:云通讯、Submail、Ucpaas)
Sms::make()->to($to)->template($templates)->data($tempData)->send();

// 只希望使用内容方式发送，可以不设置模板id和模板data(如:短信宝、云片、luosimao)
Sms::make()->to($to)->content($content)->send();

// 同时确保能通过模板和内容方式发送，这样做的好处是可以兼顾到各种类型服务商
Sms::make()->to($to)
    ->template($templates)
    ->data($tempData)
    ->content($content)
    ->send();

// 语音验证码
Sms::voice('02343')->to($to)->send();

// 语音验证码兼容模版语音(如阿里大鱼的文本转语音)
Sms::voice('02343')
    ->template('Alidayu', 'your_tts_code')
    ->data(['code' => '02343'])
    ->to($to)
    ->send();
```

### 3. 在laravel和lumen中使用

[](#3-在laravel和lumen中使用)

- 服务提供器

```
//服务提供器
'providers' => [
    ...
    Toplan\PhpSms\PhpSmsServiceProvider::class,
]

//别名
'aliases' => [
    ...
    'PhpSms' => Toplan\PhpSms\Facades\Sms::class,
]
```

- 生成配置文件

```
php artisan vendor:publish
```

生成的配置文件为config/phpsms.php，然后在该文件中按提示配置。

- 使用

详见API，示例：

```
PhpSms::make()->to($to)->content($content)->send();
```

API
===

[](#api)

API - 全局配置
----------

[](#api---全局配置)

### Sms::scheme(\[$name\[, $scheme\]\])

[](#smsschemename-scheme)

设置/获取代理器的调度方案。

> 调度配置支持热更新，即在应用系统的整个运行过程中都能随时修改。

- 设置

手动设置代理器调度方案(优先级高于配置文件)，如：

```
Sms::scheme([
    'SmsBao' => '80 backup'
    'YunPian' => '100 backup'
]);
//或
Sms::scheme('SmsBao', '80 backup');
Sms::scheme('YunPian', '100 backup');
```

- 获取

通过该方法还能获取所有或指定代理器的调度方案，如：

```
//获取所有的调度方案:
$scheme = Sms::scheme();

//获取指定代理器的调度方案:
$scheme['SmsBao'] = Sms::scheme('SmsBao');
```

> `scheme`静态方法的更多使用方法见[高级调度配置](#%E9%AB%98%E7%BA%A7%E8%B0%83%E5%BA%A6%E9%85%8D%E7%BD%AE)

### Sms::config(\[$name\[, $config\]\[, $override\]\]);

[](#smsconfigname-config-override)

设置/获取代理器的配置数据。

> 参数配置支持热更新，即在应用系统的整个运行过程中都能随时修改。

- 设置

手动设置代理器的配置数据(优先级高于配置文件)，如：

```
Sms::config([
   'SmsBao' => [
       'username' => ...,
       'password' => ...,
   ]
]);
//或
Sms::config('SmsBao', [
   'username' => ...,
   'password' => ...,
]);
```

- 获取

通过该方法还能获取所有或指定代理器的配置参数，如：

```
//获取所有的配置:
$config = Sms::config();

//获取指定代理器的配置:
$config['SmsBao'] = Sms::config('SmsBao');
```

### Sms::beforeSend($handler\[, $override\]);

[](#smsbeforesendhandler-override)

发送前钩子，示例：

```
Sms::beforeSend(function($task, $index, $handlers, $prevReturn){
    //获取短信数据
    $smsData = $task->data;
    ...
    //如果返回false会终止发送任务
    return true;
});
```

> 更多细节请查看 [task-balancer](https://github.com/toplan/task-balancer#2-task-lifecycle) 的 `beforeRun` 钩子

### Sms::beforeAgentSend($handler\[, $override\]);

[](#smsbeforeagentsendhandler-override)

代理器发送前钩子，示例：

```
Sms::beforeAgentSend(function($task, $driver, $index, $handlers, $prevReturn){
    //短信数据:
    $smsData = $task->data;
    //当前使用的代理器名称:
    $agentName = $driver->name;
    //如果返回false会停止使用当前代理器
    return true;
});
```

> 更多细节请查看 [task-balancer](https://github.com/toplan/task-balancer#2-task-lifecycle) 的 `beforeDriverRun` 钩子

### Sms::afterAgentSend($handler\[, $override\]);

[](#smsafteragentsendhandler-override)

代理器发送后钩子，示例：

```
Sms::afterAgentSend(function($task, $agentResult, $index, $handlers, $prevReturn){
     //$result为代理器的发送结果数据
     $agentName = $agentResult['driver'];
     ...
});
```

> 更多细节请查看 [task-balancer](https://github.com/toplan/task-balancer#2-task-lifecycle) 的 `afterDriverRun` 钩子

### Sms::afterSend($handler\[, $override\]);

[](#smsaftersendhandler-override)

发送后钩子，示例：

```
Sms::afterSend(function($task, $taskResult, $index, $handlers, $prevReturn){
    //$result为发送后获得的结果数组
    $success = $taskResult['success'];
    ...
});
```

> 更多细节请查看 [task-balancer](https://github.com/toplan/task-balancer#2-task-lifecycle) 的 `afterRun` 钩子

### Sms::queue(\[$enable\[, $handler\]\])

[](#smsqueueenable-handler)

该方法可以设置是否启用队列以及定义如何推送到队列。

`$handler`匿名函数可使用的参数:

- `$sms` : Sms实例
- `$data` : Sms实例中的短信数据，等同于`$sms->all()`

定义如何推送到队列：

```
//自动启用队列
Sms::queue(function($sms, $data){
    //define how to push to queue.
    ...
});

//第一个参数为true,启用队列
Sms::queue(true, function($sms, $data){
    //define how to push to queue.
    ...
});

//第一个参数为false,暂时关闭队列
Sms::queue(false, function($sms, $data){
    //define how to push to queue.
    ...
});
```

如果已经定义过如何推送到队列，还可以继续设置关闭/开启队列：

```
Sms::queue(true);//开启队列
Sms::queue(false);//关闭队列
```

获取队列启用情况：

```
$enable = Sms::queue();
//为true,表示当前启用了队列。
//为false,表示当前关闭了队列。
```

API - 发送相关
----------

[](#api---发送相关)

### Sms::make()

[](#smsmake)

生成发送短信的sms实例，并返回实例。

```
$sms = Sms::make();

//创建实例的同时设置短信内容：
$sms = Sms::make('【签名】这是短信内容...');

//创建实例的同时设置短信模版：
$sms = Sms::make('YunTongXun', 'your_temp_id');
//或
$sms = Sms::make([
    'YunTongXun' => 'your_temp_id',
    'SubMail' => 'your_temp_id',
    ...
]);
```

### Sms::voice()

[](#smsvoice)

生成发送语音验证码的sms实例，并返回实例。

```
$sms = Sms::voice();

//创建实例的同时设置验证码
$sms = Sms::voice($code);
```

> - 如果你使用`Luosimao`语音验证码，还需用在配置文件中`Luosimao`选项中设置`voiceApikey`。
> - **语音文件ID**即是在服务商配置的语音文件的唯一编号，比如阿里大鱼[语音通知](http://open.taobao.com/doc2/apiDetail.htm?spm=a219a.7395905.0.0.oORhh9&apiId=25445)的`voice_code`。
> - **模版语音**是另一种语音请求方式，它是通过模版ID和模版数据进行的语音请求，比如阿里大鱼的[文本转语音通知](http://open.taobao.com/doc2/apiDetail.htm?spm=a219a.7395905.0.0.f04PJ3&apiId=25444)。

### type($type)

[](#typetype)

设置实例类型，可选值有`Sms::TYPE_SMS`和`Sms::TYPE_VOICE`，返回实例对象。

### to($mobile)

[](#tomobile)

设置发送给谁，并返回实例。

```
$sms->to('1828*******');

//兼容腾讯云
$sms->to([86, '1828*******'])
```

### template($agentName, $id)

[](#templateagentname-id)

指定代理器设置模版或批量设置，并返回实例。

```
//设置指定服务商的模板id
$sms->template('YunTongXun', 'your_temp_id')
    ->template('SubMail', 'your_temp_id');

//一次性设置多个服务商的模板id
$sms->template([
    'YunTongXun' => 'your_temp_id',
    'SubMail' => 'your_temp_id',
    ...
]);
```

### data($key, $value)

[](#datakey-value)

设置模板短信的模板数据，并返回实例对象。

```
//单个数据
$sms->data('code', $code);

//同时设置多个数据
$sms->data([
    'code' => $code,
    'minutes' => $minutes
]);
```

> 通过`template`和`data`方法的组合除了可以实现模版短信的数据填充，还可以实现模版语音的数据填充。

### content($text)

[](#contenttext)

设置内容短信的内容，并返回实例对象。

> 一些内置的代理器(如SmsBao、YunPian、Luosimao)使用的是内容短信(即直接发送短信内容)，那么就需要为它们设置短信内容。

```
$sms->content('【签名】这是短信内容...');
```

### code($code)

[](#codecode)

设置语音验证码，并返回实例对象。

### file($agentName, $id)

[](#fileagentname-id)

设置语音文件，并返回实例对象。

```
$sms->file('Agent1', 'agent1_file_id')
    ->file('Agent2', 'agent2_file_id');

//或
$sms->file([
    'Agent1' => 'agent1_file_id',
    'Agent2' => 'agent2_fiile_id',
]);
```

### params($agentName, $params)

[](#paramsagentname-params)

直接设置参数到服务商提供的原生接口上，并返回实例对象。

```
$sms->params('Agent1', [
    'callbackUrl' => ...,
    'userData'    => ...,
]);

//或
$sms->params([
    'Agent1' => [
        'callbackUrl' => ...,
        'userData'    => ...,
    ],
    'Agent2' => [
        ...
    ],
]);
```

### all(\[$key\])

[](#allkey)

获取Sms实例中的短信数据，不带参数时返回所有数据，其结构如下：

```
[
    'type'      => ...,
    'to'        => ...,
    'templates' => [...],
    'data'      => [...], // template data
    'content'   => ...,
    'code'      => ...,   // voice code
    'files'     => [...], // voice files
    'params'    => [...],
]
```

### agent($name)

[](#agentname)

临时设置发送时使用的代理器(不会影响备用代理器的正常使用)，并返回实例，`$name`为代理器名称。

```
$sms->agent('SmsBao');
```

> 通过该方法设置的代理器将获得绝对优先权，但只对当前短信实例有效。

### send()

[](#send)

请求发送短信/语音验证码。

```
//会遵循是否使用队列
$result = $sms->send();

//忽略是否使用队列
$result = $sms->send(true);
```

> `$result`数据结构请参看[task-balancer](https://github.com/toplan/task-balancer)

自定义代理器
======

[](#自定义代理器)

- step 1

可将配置项(如果有用到)加入到`config/phpsms.php`中键为`agents`的数组里。

```
//example:
'Foo' => [
    'key' => 'your api key',
    ...
]
```

- step 2

新建一个继承`Toplan\PhpSms\Agent`抽象类的代理器类，建议代理器类名为`FooAgent`，建议命名空间为`Toplan\PhpSms`。

> 如果类名不为`FooAgent`或者命名空间不为`Toplan\PhpSms`，在使用该代理器时则需要指定代理器类，详见[高级调度配置](#%E9%AB%98%E7%BA%A7%E8%B0%83%E5%BA%A6%E9%85%8D%E7%BD%AE)。

- step 3

实现相应的接口，可选的接口有:

接口说明ContentSms发送内容短信TemplateSms发送模版短信VoiceCode发送语音验证码ContentVoice发送内容语音TemplateVoice发送模版语音FileVoice发送文件语音高级调度配置
======

[](#高级调度配置)

代理器的高级调度配置可以通过配置文件(`config/phpsms.php`)中的`scheme`项目配置，也可以通过`scheme`静态方法设置。 值得注意的是，高级调度配置的值的数据结构是数组。

### 指定代理器类

[](#指定代理器类)

如果你自定义了一个代理器，类名不为`FooAgent`或者命名空间不为`Toplan\PhpSms`， 那么你还可以在调度配置时指定你的代理器使用的类。

- 配置方式：

通过配置值中`agentClass`键来指定类名。

- 示例：

```
Sms::scheme('agentName', [
    '10 backup',
    'agentClass' => 'My\Namespace\MyAgentClass'
]);
```

### 寄生代理器

[](#寄生代理器)

如果你既不想使用内置的代理器，也不想创建文件写自定义代理器，那么寄生代理器或许是个好的选择， 无需定义代理器类，只需在调度配置时定义好发送短信和语音验证码的方式即可。

- 配置方式：

可以配置的发送过程有:

发送过程参数列表说明sendContentSms$agent, $to, $content发送内容短信sendTemplateSms$agent, $to, $tmpId, $tmpData发送模版短信sendVoiceCode$agent, $to, $code发送语音验证码sendContentVoice$agent, $to, $content发送内容语音sendTemplateVoice$agent, $to, $tmpId, $tmpData发送模版语音sendFileVoice$agent, $to, $fileId发送文件语音- 示例：

```
Sms::scheme([
    'agentName' => [
        '20 backup',
        'sendContentSms' => function($agent, $to, $content){
            // 获取配置(如果设置了的话):
            $key = $agent->key;
            ...
            // 可使用的内置方法:
            $agent->curlGet($url, $params); //get
            $agent->curlPost($url, $params); //post
            ...
            // 更新发送结果:
            $agent->result(Agent::SUCCESS, true);
            $agent->result(Agent::INFO, 'some info');
            $agent->result(Agent::CODE, 'your code');
        },
        'sendVoiceCode' => function($agent, $to, $code){
            // 发送语音验证码，同上
        }
    ]
]);
```

Todo
====

[](#todo)

- 重新实现云通讯代理器，去掉`lib/CCPRestSmsSDK.php`
- 重新实现云之讯代理器，去掉`lib/Ucpaas.php`
- 升级云片接口到v2版本

License
=======

[](#license)

MIT

###  Health Score

46

—

FairBetter than 93% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity54

Moderate usage in the ecosystem

Community30

Small or concentrated contributor base

Maturity69

Established project with proven stability

 Bus Factor1

Top contributor holds 92.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~19 days

Recently: every ~14 days

Total

32

Last Release

3224d ago

Major Versions

0.3.0 → 1.0.02015-12-17

### Community

Maintainers

![](https://www.gravatar.com/avatar/1b598ead57cbabafb3d2eea7db7901e3f51a37108750cc2552fc468c3364ee21?d=identicon)[toplan](/maintainers/toplan)

---

Top Contributors

[![toplan](https://avatars.githubusercontent.com/u/7815594?v=4)](https://github.com/toplan "toplan (351 commits)")[![medz](https://avatars.githubusercontent.com/u/5564821?v=4)](https://github.com/medz "medz (6 commits)")[![domainname](https://avatars.githubusercontent.com/u/1830237?v=4)](https://github.com/domainname "domainname (4 commits)")[![branchzero](https://avatars.githubusercontent.com/u/7685609?v=4)](https://github.com/branchzero "branchzero (4 commits)")[![king19800105](https://avatars.githubusercontent.com/u/22978667?v=4)](https://github.com/king19800105 "king19800105 (3 commits)")[![hiship](https://avatars.githubusercontent.com/u/183052291?v=4)](https://github.com/hiship "hiship (3 commits)")[![yangliuyu](https://avatars.githubusercontent.com/u/1361821?v=4)](https://github.com/yangliuyu "yangliuyu (2 commits)")[![darkal](https://avatars.githubusercontent.com/u/9945996?v=4)](https://github.com/darkal "darkal (2 commits)")[![hzkoala](https://avatars.githubusercontent.com/u/1684348?v=4)](https://github.com/hzkoala "hzkoala (2 commits)")[![cuikangyi](https://avatars.githubusercontent.com/u/5945838?v=4)](https://github.com/cuikangyi "cuikangyi (1 commits)")

---

Tags

phpsmssmsphpsmsphpsmssms library

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/toplan-phpsms/health.svg)

```
[![Health](https://phpackages.com/badges/toplan-phpsms/health.svg)](https://phpackages.com/packages/toplan-phpsms)
```

###  Alternatives

[djunehor/laravel-sms

Send SMS from your laravel application

385.3k1](/packages/djunehor-laravel-sms)[amirbagh75/smsir-php

Unofficial sms.ir PHP Package

181.2k](/packages/amirbagh75-smsir-php)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
