alexandr-mironov / php8-smpp
PHP SMPP 客户端库,基于 onlinecity/php-smpp 的分支
Requires
- php: 8.*
- ext-mbstring: *
- ext-sockets: *
Requires (Dev)
- phpstan/phpstan: 1.4.8
This package is auto-updated.
Last update: 2024-08-30 01:17:59 UTC
README
PHP8 上的 SMPP 客户端 (v 3.4)
注意!
开发中!尚未准备就绪用于生产环境!
以下是从 https://github.com/alexandr-mironov/php-smpp 复制的说明
PHP SMPP (v3.4) 客户端
安装
composer require alexandr-mironov/php8-smpp
此客户端的包装器示例(php>=7.0)。在这种情况下,我们得到了 ALPHANUMERIC 发送者值 'github_example'
<?php declare(strict_types=1); namespace app\components\Sms; use Exception; use smpp\{Address, Client as SmppClient, Smpp, transport\Socket}; class SmsBuilder { /** @var string 11 chars limit */ public const DEFAULT_SENDER = 'example'; protected Socket $transport; protected SmppClient $smppClient; protected bool $debug = false; protected Address $from; protected Address $to; protected string $login; protected string $password; /** * SmsBuilder constructor. * * @param string $address SMSC IP * @param int $port SMSC port * @param string $login * @param string $password * @param int $timeout timeout of reading PDU in milliseconds * @param bool $debug - debug flag when true output additional info */ public function __construct( string $address, int $port, string $login, string $password, int $timeout = 10000, bool $debug = false ) { $this->transport = new Socket([$address], $port); // Activate binary hex-output of server interaction $this->transport->debug = $debug; $this->transport->setRecvTimeout($timeout); $this->smppClient = new SmppClient($this->transport); $this->login = $login; $this->password = $password; $this->from = new Address(self::DEFAULT_SENDER, SMPP::TON_ALPHANUMERIC); } /** * @param string $sender * @param int $ton * * @return $this * @throws Exception */ public function setSender(string $sender, int $ton): SmsBuilder { return $this->setAddress($sender, 'from', $ton); } /** * @param string $address * @param string $type * @param int $ton * @param int $npi * * @return $this * @throws Exception */ protected function setAddress( string $address, string $type, int $ton = SMPP::TON_UNKNOWN, int $npi = SMPP::NPI_UNKNOWN ): SmsBuilder { // some example of data preparation if ($ton === SMPP::TON_INTERNATIONAL) { $npi = SMPP::NPI_E164; } $this->$type = new Address($address, $ton, $npi); return $this; } /** * @param string $address * @param int $ton * * @return $this * @throws Exception */ public function setRecipient(string $address, int $ton): SmsBuilder { return $this->setAddress($address, 'to', $ton); } /** * @param string $message * * @throws Exception */ public function sendMessage(string $message): void { $this->transport->open(); $this->smppClient->bindTransceiver($this->login, $this->password); // strongly recommend use SMPP::DATA_CODING_UCS2 as default encoding in project to prevent problems with non latin symbols $this->smppClient->sendSMS($this->from, $this->to, $message, null, SMPP::DATA_CODING_UCS2); $this->smppClient->close(); } }
此包装器实现了一种Builder模式,用法示例
<?php // replace address, port, login and password to your values (new your_namespace\SmsBuilder('192.168.1.1', '2776', 'your_login', 'your_password', 10000)) ->setRecipient('79000000000', \smpp\SMPP::TON_INTERNATIONAL) //msisdn of recipient ->sendMessage('Тестовое сообщение на русском and @noth3r$Ymb0ls');
原始描述
基于PHP的SMPP客户端库
这是一个简化版的SMPP客户端库,用于通过 SMPP v3.4 发送或接收短信。
除了客户端,此库还包含一个将UTF-8文本转换为GSM 03.38编码的编码器,以及一个套接字包装器。套接字包装器在PHP的套接字扩展之上提供了连接池、IPv6和超时监控功能。
与首次发布相比,此库已发生重大变化,需要命名空间并包含一些工作组件。您可以在 1.0.1-namespaced 中找到该版本。
此库需要 sockets PHP 扩展,不支持在Windows上运行。还有一个兼容Windows的版本。
连接池
您可以指定一个连接列表,让 SocketTransport 依次或随机尝试每个连接。如果您提供一个具有多个A/AAAA-记录的主机名,它也会尝试每个记录。如果您想监控DNS查找,请在构建传输之前将 defaultDebug 设置为 true。
(可配置的)发送超时控制它将等待每个服务器超时的时间。根据超时时间,尝试服务器列表可能会花费很长时间。您可以在连接尝试之前和之后更改超时时间。
传输支持IPv6,并且在可用的情况下会优先选择IPv6地址。您可以通过设置 forceIpv6 或 forceIpv4 来修改此功能,强制它只使用IPv6或IPv4。
除了DNS查找之外,它还会使用 gethostbyname() 查找本地IPv4地址,因此 "localhost" 对IPv4有效。对于IPv6 localhost,指定 "::1"。
实现说明
- 您不能作为接收器连接,尽管SMPP v.3.4支持此操作
- SMPP的 SUBMIT_MULTI 操作(向一组接收者发送短信)目前不支持。您可以轻松添加它。
- 套接字在 read() 上达到超时(但不是 readAll 或 write)时将返回 false。您可以使用此功能来实现 enquire_link 策略。如果您需要每30秒不活动后发送 enquire_link,请设置30秒的超时,并在 readSMS() 返回 false 后发送 enquire_link 命令。
- 上述示例假定SMSC默认数据编码为 GSM 03.38。
- 如果您想接收投递回执,请记得激活已注册的投递(设置为 SMPP::REG_DELIVERY_SMSC_BOTH / 0x01)。
- SmppClient 和传输组件都支持调试回调,默认为 error_log。使用此功能将调试信息重定向。
常见问题解答
我可以用这个从我的网站发送消息吗?
不单独进行。PHP处理网站上的请求后,它会关闭所有连接。大多数SMPP提供商不希望您打开和关闭连接,您应该保持它们处于活动状态,并定期发送enquire_link命令。这意味着您可能需要获取某种长期运行的过程,例如使用进程控制函数,并实现一种队列系统,您可以从网站推送到该系统。这需要服务器级别的shell访问权限,以及对Unix进程的了解。
我如何接收投递回执或短信?
要接收投递回执或短信,您必须连接一个接收器,而不仅仅是发送器。这个接收器必须等待投递回执到达,这意味着您可能需要使用进程控制函数。
我们有一个开源实现,可在php-smpp-worker查看,以获取灵感,但我们无法帮助您制作自己的。也许您应该调查您的SMSC提供商是否可以提供基于HTTP的API,或使用如kannel这样的即插即用软件,此项目仅提供协议实现和基本的套接字包装器。
我无法发送超过160个字符?
有三种内置方法可以发送连接短信(csms);CSMS_16BIT_TAGS、CSMS_PAYLOAD、CSMS_8BIT_UDH。CSMS_16BIT_TAGS是默认的,如果不起作用,请尝试另一种。
这个库与PHP 5.2.x兼容吗?
它在PHP 5.3上进行了测试,但已知也与5.2兼容。
它能在Windows上运行吗?
它需要套接字扩展,这在Windows上可用,但不完整。请使用windows-compatible版本,它使用fsockopen和流函数。
为什么我没有看到任何调试输出?
请记住为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服务器的情况下测试客户端库吗?
许多服务提供商可以为您提供演示账户,但您也可以使用 logica opensmpp 模拟器(Java)或 smsforum 客户端测试工具(Linux 可执行文件)。除了与多个真实SMPP服务器进行测试外,此库还对这些模拟器进行了测试。
这里没有提到我的问题,我该怎么办?
请获取完整的调试信息,并在github上创建一个问题。确保不要包括 BindTransmitter 调用的发送 PDU十六进制代码,因为其中将包含您的用户名和密码。其他十六进制输出均可,非常感谢。任何PHP警告或通知也可能很重要。请包括您连接的SMPP服务器信息以及任何具体细节。