benmorel / gsm-charset-converter
将 GSM 03.38 字符串转换为 UTF-8,反之亦然
Requires
- php: ^7.4 || ^8.0
- ext-mbstring: *
Requires (Dev)
- php-coveralls/php-coveralls: ^2.4
- phpunit/phpunit: ^8.0 || ^9.0
- vimeo/psalm: 4.29.0
README
这是一个 PHP 库,用于将 GSM 03.38(用于短信消息的字符集)转换为 UTF-8,反之亦然。
此库经过良好的测试。所使用的字符映射已与多个来源进行交叉校验,并在必要时在真实的短信网关上进行测试。
库提供可选的转写功能:不受支持的字符可以用类似变体替换。例如,ë
字符可以替换为 e
。
已知限制
- 目前仅支持默认字母表和扩展表;这是根据标准,每个设备和网络元素都必须支持的字母表。 存在其他字母表,但此项目目前不旨在支持它们。
- 转写可能不适用于所有在 GSM 字符集中可能有类似等效字符的字符;此库支持拉丁1字符和几种其他语言的转写。如果您认为另一个 UTF-8 字符可以转写,请 提出问题!
安装
此库可以通过 Composer 安装
composer require benmorel/gsm-charset-converter
要求
此库需要 PHP >= 7.4 和 mbstring
扩展。
项目状态和发布流程
此库正在开发中。
当前版本编号为 0.x.y
。当引入非破坏性更改(添加新方法、优化现有代码等)时,y
增量。
当引入破坏性更改时,总是开始新的 0.x
版本周期。
因此,将项目锁定到给定的版本周期,例如 0.3.*
是安全的。
如果您需要升级到较新的版本周期,请查看 发布历史,以了解每个进一步的 0.x.0
版本引入的更改列表。
使用
将 GSM 03.38 字符串转换为 UTF-8
convertGsmToUtf8()
方法接受一个参数
use BenMorel\GsmCharsetConverter\Converter; $converter = new Converter(); $utf8 = $converter->convertGsmToUtf8('...');
输入字符串必须是有效的 GSM 03.38 字符串,否则将抛出 InvalidArgumentException
。 输入字符串预期已解包:8位字节中的7位字符,带有前导零位,就像ASCII字符一样。
将 UTF-8 字符串转换为 GSM 03.38
convertUtf8ToGsm()
方法接受3个参数
- 有效的 UTF-8 输入字符串;
- 是否尝试转写不兼容的字符;
- 替换未知字符的可选字符串。
如果输入字符串不是有效的 UTF-8,将抛出 InvalidArgumentException
。
输出是一个解包的 GSM 03.38 字符串。
无转写
$gsm = $converter->convertUtf8ToGsm('Helló', false, '?'); // Hell?
如果未提供第三个参数,并且字符串包含与 GSM 03.38 不兼容的字符,将抛出 InvalidArgumentException
。
有转写
$gsm = $converter->convertUtf8ToGsm('Helló', true, '?'); // Hello
如果未提供第三个参数,并且字符串包含与 GSM 03.38 不兼容且无法转写的字符,将抛出 InvalidArgumentException
。
清理 UTF-8 字符串以确保消息在 GSM 字符集中发送
如今,大多数在线短信网关接受 UTF-8 作为输入;然而,其中一些网关没有提供强制消息在 GSM 字符集中发送的方法。
因此,如果你的短信是以Unicode(UCS-2)格式发送,可能会产生额外费用,因为短信会在多个部分中分段,仅仅是因为你的短信消息包含一个未预见的带重音符号的字符或表情符号。
该库提供了一个方法 cleanUpUtf8String()
,可以避免这些意外,该方法返回一个只包含可以安全转换为GSM字符集的字符的UTF-8字符串。
此方法接受与convertUtf8ToGsm()
相同的参数。
$utf8 = $converter->cleanUpUtf8String('Helló', false, '?'); // Hell? $utf8 = $converter->cleanUpUtf8String('Helló', true, '?'); // Hello
将7位字符串打包成8位二进制字符串
为了将160个7位字符装入140字节短信中,字符必须打包成一个二进制,8位字符串。Packer
类提供了打包和解包这种格式的字符串的功能
use BenMorel\GsmCharsetConverter\Packer; $packer = new Packer(); $packed = $packer->pack('ABC'); // the binary string 41E110 $string = $packer->unpack("\x41\xE1\x10"); // ABC
请注意,如果输入字符串包含8位字符(即首位设置为1的字符),则pack()
将抛出InvalidArgumentException
异常。