ljmaskey / php-cmf-bindings
将bitcoinclassic/cmf-bindings端口移植到PHP
Requires
- php-64bit: ^8.2
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.26
- phpstan/phpstan: ^1.10
- phpstan/phpstan-deprecation-rules: ^1.1
- phpstan/phpstan-phpunit: ^1.3
- phpstan/phpstan-strict-rules: ^1.5
- phpunit/phpunit: ^10.3
This package is not auto-updated.
Last update: 2024-09-29 16:58:09 UTC
README
这是实现一个PHP端口紧凑消息格式绑定项目的尝试。
在创建此端口时,我们参考了Java和C#实现,但测试受到了所有不同实现的影响。
什么是紧凑消息格式?
正如原始项目README中所述
Bitcoin Classic引入了紧凑消息格式,作为一种非常简单但功能强大的格式来编码和解码任何类型的消息。
紧凑消息格式是一种基于键/值对的格式。每个键/值对称为令牌,一条消息由一系列令牌组成。
实现细节
其他实现需要给MessageBuilder
和MessageParser
提供一个字节数组,而PHP没有这种概念。相反,此包中的类将接受一个数组(特别是列表)或一个流资源。
为了方便起见,当在MessageBuilder
上使用addByteArray
方法时,此实现将允许给定数组中的项为字节数值或单个ASCII字符(或这些的组合)。当给定一个ASCII字符时,包将将其转换为相应的字节数值后再将其添加到消息中。
同样,当MessageParser
被给定一个数组作为其数据源(而不是流资源)时,该数组可以包含字节数值或单个ASCII字符。不过,无论输入如何,调用解析器的getByteArray
将始终返回仅包含字节数值的数组。
由于PHP没有支持方法重载,因此MessageBuilder
具有显式命名的add...
方法,这些方法对应于在MessageParser
上显式定义的get...
方法。
与其他实现不同,没有显式调用close()
方法。
当从流中读取字节时,忽略位置参数。相反,包将始终从流中读取下一个字节(或字节序列)。
使用包
为了展示包的使用,我们将使用原始项目中的相同简短示例:一个包含3个令牌的消息,每个令牌都有一个名称和值。
Name=Paris Population=2229621 Area=105.6
消息创建
对于消息创建,我们使用建造者模式,形式为MessageBuilder
类。
MessageBuilder
类有一系列add...()
方法,每个方法都会将一个令牌追加到您的消息中。添加到消息中的每个值都需要一个标签,标签是一个介于0到65535(包含)之间的整数。
$bytes = []; $builder = new MessageBuilder($bytes, 0); $builder->addString(CITY_NAME_TAG, 'Paris'); $builder->addInt(CITY_POPULATION_TAG, 2229621); $builder->addDouble(CITY_AREA_TAG, 105.6);
消息解析
MessageParser使用更多SOX解析器方法,即调用MessageParser.Next()
,然后您可以向解析器请求标签和实际值。
$parser = new MessageParser($inputStream, 0, $inputStreamLength); while ($parser->next() == State.FoundTag) { if ($parser->tag() == CITY_POPULATION_TAG) { $population = $parser->getInt(); break; } }
异常处理
\InvalidArgumentException
当方法中传入的数据有问题时,包将抛出此异常。这可能包括当期望列表数组时传递非列表数组,或者当不允许时传递负数。请注意,这不包括处理底层数据时发生的错误:这些将抛出SerializationException
或UnserializationException
。
\InvalidArgumentException表示应由调用代码解决的问题。
SerializationException
,UnserializationException
这些异常是在处理的数据存在错误时抛出的。这些异常中的一种解决方式取决于数据的原始来源。
InternalPackageException
这些异常是在包的自身代码中发生意外情况时抛出的。
这些异常应该被报告,因为它们需要由包来解决。