PHP SMPP客户端库,基于onlinecity/php-smpp的分支

1.3.0.9 2022-12-02 20:14 UTC

This package is auto-updated.

Last update: 2024-09-23 23:24:01 UTC


README

安装

composer require alexandr-mironov/php-smpp

此客户端的包装器示例(php>=7.0)。在这种情况下,我们得到了ALPHANUMERIC发送者值'github_example'

<?php

namespace your_namespace;

use smpp\{ Address, SMPP, Client as SmppClient, transport\Socket};

class SmsBuilder
{
    const DEFAULT_SENDER = 'github_example';
    protected $transport;
    protected $smppClient;
    protected $debug = false;
    protected $from;
    protected $to;
    protected $login;
    protected $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);
        $this->transport->setRecvTimeout($timeout);
        $this->smppClient = new SmppClient($this->transport);

        // Activate binary hex-output of server interaction
        $this->smppClient->debug = $debug;
        $this->transport->debug = $debug;

        $this->login = $login;
        $this->password = $password;

        $this->from = new Address(self::DEFAULT_SENDER,SMPP::TON_ALPHANUMERIC);
    }

    /**
     * @param $sender
     * @param $ton
     * @return $this
     * @throws \Exception
     */
    public function setSender($sender, $ton)
    {
        return $this->setAddress($sender, 'from', $ton);
    }

    /**
     * @param $address
     * @param $ton
     * @return $this
     * @throws \Exception
     */
    public function setRecipient($address, $ton)
    {
        return $this->setAddress($address, 'to', $ton);
    }

    /**
     * @param $address
     * @param string $type
     * @param int $ton
     * @param int $npi
     * @return $this
     * @throws \Exception
     */
    protected function setAddress($address, string $type, $ton = SMPP::TON_UNKNOWN, $npi = SMPP::NPI_UNKNOWN)
    {
        // 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 $message
     */
    public function sendMessage(string $message)
    {
        $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兼容版本,该版本使用fsockopen和流函数。

为什么我没有看到任何调试输出?
请记得为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服务器的情况下测试客户端库吗?
许多服务提供商可以为您提供演示账户,但您也可以使用logica opensmpp 模拟器(Java)或smsforum 客户端测试工具(Linux 二进制文件)。除了许多真实的 SMPP 服务器外,这个库还对这些模拟器进行了测试。

这里没有提到我的问题,我该怎么办?
请获取完整的调试信息,并在 github 上开启一个 Issue。请确保不要包含 BindTransmitter 调用的发送 PDU 十六进制代码,因为它将包含您的用户名和密码。其他十六进制输出是可以的,也非常感谢。任何 PHP 警告或通知也可能很重要。请包含您连接到的 SMPP 服务器信息以及任何具体细节。