eloquent / endec
PHP 的多功能编码实现。
Requires
- php: >=5.3
- eloquent/confetti: ~0.3.1
- evenement/evenement: >=1,<3
- icecave/isolator: ~2
- react/stream: >=0.3,<0.5
Requires (Dev)
- eloquent/liberator: ~2
- icecave/archer: ~1
This package is auto-updated.
Last update: 2020-02-06 04:53:18 UTC
README
PHP 的多功能编码实现。
安装和文档
- 作为 Composer 包 eloquent/endec 可用。
- API 文档 可用。
Endec 是什么?
Endec 是一个通用的 PHP 编码库,除了支持常规基于字符串的编码和解码方法外,还支持流数据的编码和解码。 Endec 随附了一些常见的编码,易于使用,并在必要时可以简单地通过自定义编码进行扩展。
使用方法
字符串
Endec 可以处理字符串,类似于 PHP 标准库中的编码函数。所有的编解码类都有一个静态的 instance()
方法,仅作为方便(它们不是单例)。
use Eloquent\Endec\Base32\Base32; $codec = new Base32; echo $codec->encode('foobar'); // outputs 'MZXW6YTBOI======' echo $codec->decode('MZXW6YTBOI======'); // outputs 'foobar' echo Base32::instance()->encode('foobar'); // outputs 'MZXW6YTBOI======' echo Base32::instance()->decode('MZXW6YTBOI======'); // outputs 'foobar'
流过滤器
PHP 本身支持 流过滤器。可以使用 stream_filter_append 或 stream_filter_prepend 将任意数量的过滤器添加到任意流中,并使用 stream_filter_remove 移除。所有 Endec 的编码都可作为 流过滤器 使用。
use Eloquent\Endec\Endec; Endec::registerFilters(); $path = '/path/to/file'; $stream = fopen($path, 'wb'); stream_filter_append($stream, 'endec.base32-encode'); fwrite($stream, 'fo'); fwrite($stream, 'ob'); fwrite($stream, 'ar'); fclose($stream); echo file_get_contents($path); // outputs 'MZXW6YTBOI======' $stream = fopen($path, 'rb'); stream_filter_append($stream, 'endec.base32-decode'); $data = fread($stream, 3); $data .= fread($stream, 3); $data .= fread($stream, 2); fclose($stream); echo $data; // outputs 'foobar'
React 流
可以从 编码器、解码器或编解码器 获取流。 Endec 的流实现了来自 React 库的 WritableStreamInterface 和 ReadableStreamInterface,因此可以异步使用。
use Eloquent\Endec\Base32\Base32; $codec = new Base32; $encodeStream = $codec->createEncodeStream(); $decodeStream = $codec->createDecodeStream(); $encoded = ''; $encodeStream->on( 'data', function ($data, $stream) use (&$encoded) { $encoded .= $data; } ); $decoded = ''; $decodeStream->on( 'data', function ($data, $stream) use (&$decoded) { $decoded .= $data; } ); $encodeStream->pipe($decodeStream); $encodeStream->write('fo'); $encodeStream->write('ob'); $encodeStream->end('ar'); echo $encoded; // outputs 'MZXW6YTBOI======' echo $decoded; // outputs 'foobar'
错误处理
处理字符串时的错误处理就像捕获异常一样简单。所有抛出的异常都实现了 TransformExceptionInterface
use Eloquent\Endec\Base32\Base32; use Eloquent\Endec\Exception\EncodingExceptionInterface; $codec = new Base32; try { $codec->decode('!!!!!!!!'); } catch (EncodingExceptionInterface $e) { echo 'Unable to decode'; }
使用流过滤器时,错误处理比较困难,因为 PHP 似乎只是简单地 忽略过滤器产生的错误。如果 fwrite()
写入 0 字节,这通常表明发生了错误。
use Eloquent\Endec\Endec; Endec::registerFilters(); $path = '/path/to/file'; $stream = fopen($path, 'wb'); stream_filter_append($stream, 'endec.base32-decode'); if (!fwrite($stream, '!!!!!!!!')) { echo 'Unable to decode'; } fclose($stream);
使用 React 流时,只需处理 error
事件。
use Eloquent\Endec\Base32\Base32; $codec = new Base32; $decodeStream = $codec->createDecodeStream(); $decodeStream->on( 'error', function ($error, $stream) { echo 'Unable to decode'; } ); $decodeStream->end('!!!!!!!!');
内置编码
Endec 默认支持多种常见编码。对于有相关规范文档的编码,Endec 旨在达到 100% 的规范一致性。支持的编码包括
- Base64 来自 RFC 4648
- MIME消息体的Base64编码 来自 RFC 2045
- 具有URL和文件名安全字母表的Base64 来自 RFC 4648
- Base32 来自 RFC 4648
- 具有扩展十六进制字母表的Base32 来自 RFC 4648
- Base16(十六进制) 来自 RFC 4648
- URI百分编码 来自 RFC 3986
内置流过滤器
所有 Endec 编码均作为流过滤器提供。在使用之前,必须通过调用 Endec::registerFilters()
(多次调用此方法是安全的)在全局范围内注册过滤器。可用的流过滤器包括
- endec.base64-encode
- endec.base64-decode
- endec.base64mime-encode(另请参阅PHP的 convert.base64-encode)
- endec.base64mime-decode(另请参阅PHP的 convert.base64-decode)
- endec.base64url-encode
- endec.base64url-decode
- endec.base32-encode
- endec.base32-decode
- endec.base32hex-encode
- endec.base32hex-decode
- endec.base16-encode
- endec.base16-decode
- endec.uri-encode
- endec.uri-decode
编码器、解码器和编解码器
大多数 Endec 功能是通过 编码器、解码器 和 编解码器(编解码器只是编码器和解码器的组合)提供的。所有内置的 Endec 编码都作为编解码器实现,但也可能实现独立的编码器或解码器。
所有编码器实现 EncoderInterface,所有解码器实现 DecoderInterface,所有编解码器实现 EncoderInterface、DecoderInterface 和 CodecInterface。这允许类型提示准确地表达需求。
实现自定义编码
编码器和解码器建立在 Confetti 转换之上。有关实现转换的详细信息,请参阅Confetti的实现转换文档。
例如,给定以下转换
use Eloquent\Confetti\TransformInterface; class Rot13Transform implements TransformInterface { public function transform($data, &$context, $isEnd = false) { return array(str_rot13($data), strlen($data)); } }
创建相关的编码器、解码器或编解码器非常简单
use Eloquent\Endec\Codec; use Eloquent\Endec\Decoder; use Eloquent\Endec\Encoder; $transform = new Rot13Transform; $encoder = new Encoder($transform); echo $encoder->encode('foobar'); // outputs 'sbbone' $decoder = new Decoder($transform); echo $decoder->decode('foobar'); // outputs 'sbbone' $codec = new Codec($transform, $transform); echo $codec->decode($codec->encode('foobar')); // outputs 'foobar'
请注意,编解码器在编码和解码时使用相同的转换,仅因为rot13是互逆的。大多数编解码器将需要分别使用编码和解码转换。