glushkovds / php-smpp
实现SMPP v3.4协议。包括发送和监听USSD。
Requires
- php: >=7.4.0
- ext-sockets: *
Requires (Dev)
- phpunit/phpunit: >7.0
This package is auto-updated.
Last update: 2024-09-22 08:54:03 UTC
README
允许发送和读取短信和USSD。
这是一个简化的SMPP客户端库,用于通过SMPP v3.4发送或接收短信。
除了客户端,此库还包含一个将UTF-8文本转换为GSM 03.38编码的编码器,以及一个套接字包装器。套接字包装器在PHP的套接字扩展之上提供了连接池、IPv6和超时监控功能。
此库与父级相比已经发生了显著变化。
此库需要sockets PHP扩展,且不支持Windows。
继承
此实现基于php-smpp库
主要区别
- 发送和监听USSD消息
- 使用Pdu、ShortMessage、Sms等类进行面向对象的方式
- 支持PSR-1、4、12
- 需要php7.4+
- Phpunit自动测试
安装
composer require glushkovds/php-smpp "^0.5"
基本用法示例
要发送短信,您可以这样做
<?php require_once 'vendor/autoload.php'; $service = new \PhpSmpp\Service\Sender(['smschost.net'], 'login', 'pass'); $smsId = $service->send(79001001010, 'Hello world!', 'Sender');
要接收短信(或投递回执)
<?php require_once 'vendor/autoload.php'; $service = new \PhpSmpp\Service\Listener(['smschost.net'], 'login', 'pass'); $service->listen(function (\PhpSmpp\Pdu\Sm $sm) { var_dump($sm->msgId); if ($sm instanceof \PhpSmpp\Pdu\DeliverReceiptSm) { var_dump($sm->state); var_dump($sm->state == \PhpSmpp\SMPP::STATE_DELIVERED); // do some job with delivery receipt } else { echo 'not receipt'; } });
要发送USSD,您可以这样做
<?php require_once 'vendor/autoload.php'; $service = new \PhpSmpp\Service\Sender(['smschost.net'], 'login', 'pass'); $smsId = $service->sendUSSD(79001001010, 'Hello world!', 'Sender', []);
要接收USSD
require_once 'vendor/autoload.php'; $service = new \PhpSmpp\Service\Listener(['smschost.net'], 'login', 'pass'); $service->listen(function (\PhpSmpp\Pdu\Pdu $pdu) { var_dump($pdu->id); var_dump($pdu->sequence); if ($pdu instanceof \PhpSmpp\Pdu\Ussd) { var_dump($pdu->status); var_dump($pdu->source->value); var_dump($pdu->destination->value); var_dump($pdu->message); // do some job with ussd } });
使用模拟传输进行代码测试(也为监听器提供)
<?php require_once 'vendor/autoload.php'; $service = new \PhpSmpp\Service\Sender(['smschost.net'], 'login', 'pass'); $service->client->setTransport(new \PhpSmpp\Transport\FakeTransport()); $smsId = $service->send(79001001010, 'Hello world!', 'Sender');
连接池
您可以指定一系列连接,让SocketTransport按顺序或随机尝试每个连接。如果给它一个具有多个A/AAAA记录的主机名,它也会尝试每个记录。如果您想监控DNS查找,在构造传输之前将defaultDebug设置为true。
(可配置的)发送超时控制它将等待每个服务器超时多长时间。尝试长列表的服务器可能需要很长时间,具体取决于超时。您可以在建立连接尝试之前和之后更改超时。
传输支持IPv6,并在可用时优先使用IPv6地址。您可以通过设置forceIpv6或forceIpv4来修改此功能,以强制仅使用IPv6或IPv4。
除了DNS查找外,它还会使用gethostbyname()查找本地IPv4地址,因此“localhost”适用于IPv4。对于IPv6 localhost,指定“::1”。
实现说明
- 目前不支持SMPP的SUBMIT_MULTI操作,该操作将短信发送到收件人列表。您可以轻松添加它。
- 套接字在read()超时时将返回false(但不是readAll或write)。您可以使用此功能实现enquire_link策略。如果您需要每30秒的空闲活动发送enquire_link,请设置超时为30秒,并在readSMS()返回false后发送enquire_link命令。
- 上面的示例假设SMSC的默认数据编码为GSM 03.38。
- 如果您想获取投递回执,请确保已启用已注册的投递(设置为SMPP::REG_DELIVERY_SMSC_BOTH / 0x01)。
- SmppClient和传输组件都支持一个调试回调,默认为error_log。使用此功能重定向调试信息。
常见问题解答
我无法发送超过160个字符
有三个内置方法可以发送连接短信(csms):CSMS_16BIT_TAGS、CSMS_PAYLOAD、CSMS_8BIT_UDH。CSMS_16BIT_TAGS是默认值,如果它不起作用,请尝试另一个。
它可以在Windows上运行吗?
也许吧!我认为这不太好。但你不妨试试,甚至可以贡献支持Windows特性的功能。
为什么我没有看到任何调试输出呢?
请记得为SocketTransport和SmppClient实现一个调试回调,否则它们默认使用error_log,它可能或不打印到屏幕。
为什么我会收到'res_nsend()失败'或'无法连接到任何指定的主机'的错误?
你提供商的DNS服务器可能存在IPv6地址(AAAA记录)的问题。尝试设置SocketTransport::$forceIpv4=true;
。你也可以尝试指定一个IP地址(或IP地址列表)。在构造传输之前设置SocketTransport:$defaultDebug=true;
也有助于解决连接问题。
我已经尝试强制使用IPv4和/或指定IP地址,但我仍然收到'无法连接到任何指定的主机'的错误?
这可能是防火墙问题阻止了你的连接,或者完全是其他问题。确保调试输出被启用并显示。如果你看到类似于'Socket connect to 1.2.3.4:2775 failed; Operation timed out'的信息,这意味着无法建立连接。如果不是防火墙问题,你可以尝试增加连接超时。sendTimeout也指定了连接超时,调用$transport->setSendTimeout(10000);
来设置10秒超时。
为什么我会收到'Failed to read reply to command: 0x4','Message Length is invalid'或'Error in optional part'错误?
很可能是你的SMPP提供商不支持消息字段以NULL终止。关于这个问题规范并不明确,所以有一个开关。设置SmppClient::$sms_null_terminate_octetstrings = false;
然后再次尝试。
'绑定失败'是什么意思?
这通常意味着你的SMPP提供商拒绝了你的登录凭证,即你的用户名或密码。
我可以在没有SMPP服务器的情况下测试客户端库吗?
是的,但不是完整功能,通过FakeTransport类。
你还可以尝试从官方SMPP网站上的模拟器:https://smpp.org/smpp-testing-development.html
这里没有提到我的问题,我该怎么办?
请获取完整的调试信息,并在GitHub上创建一个问题。确保不要包含BindTransmitter调用的发送PDU十六进制代码,因为它将包含你的用户名和密码。其他十六进制输出是可行的,并且非常受欢迎。任何PHP警告或通知也可能很重要。请包括你连接的SMPP服务器信息,以及任何具体情况。