cluvit/php-smpp

实现 SMPP v3.4 协议。包括发送和监听 USSD。

dev-master 2024-07-29 09:47 UTC

This package is auto-updated.

Last update: 2024-09-29 10:12:33 UTC


README

Build Status Latest Stable Version Total Downloads Latest Unstable Version License

允许发送和读取 SMS 和 USSD。

这是一个简化版的 SMPP 客户端库,用于通过 SMPP v3.4 发送或接收短信。

除了客户端,此库还包含一个编码器,用于将 UTF-8 文本转换为 GSM 03.38 编码,以及一个套接字包装器。套接字包装器在 PHP 的套接字扩展之上提供了连接池、IPv6 和超时监控功能。

此库与其父库相比已发生了显著变化。

此库需要 PHP 的 sockets 扩展,并且不支持 Windows。

继承

此实现基于 php-smpp 库

主要区别

  1. 发送和监听 USSD 消息
  2. 使用 Pdu、ShortMessage、Sms 等类进行面向对象的方式
  3. 支持 PSR-1、4、12
  4. 需要 php7.4+
  5. Phpunit 自动测试

安装

composer require cluvit/php-smpp:dev-master

基本用法示例

要发送 SMS,你可以这样做

<?php
require_once 'vendor/autoload.php';

$service = new \PhpSmpp\Service\Sender(['smschost.net'], 'login', 'pass');
$smsId = $service->send(79001001010, 'Hello world!', 'Sender');

要接收 SMS(或投递回执)

<?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
    }
});

使用模拟传输测试你的代码(也适用于 Listener)

<?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 操作,用于将 SMS 发送到一组接收者,目前不支持。不过你可以轻松添加它。
  • 如果 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 个字符
有三种内置方法用于发送连接 SMS(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连接到1.2.3.4:2775失败;操作超时'的信息,这意味着无法建立连接。如果不是防火墙问题,你可以尝试增加连接超时。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上打开一个issue。请确保不要包含绑定发送器的PDU十六进制代码,因为它将包含你的用户名和密码。其他十六进制输出是正常的,也受到欢迎。任何PHP警告或通知也可能很重要。请包括你连接到的SMPP服务器信息,以及任何具体信息。