eloquent/endec

此包已被 弃用 并不再维护。没有建议的替代包。

PHP 的多功能编码实现。

0.2.1 2014-05-21 01:03 UTC

This package is auto-updated.

Last update: 2020-02-06 04:53:18 UTC


README

PHP 的多功能编码实现。

The most recent stable version is 0.2.1 Current build status image Current coverage status image

安装和文档

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_appendstream_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 库的 WritableStreamInterfaceReadableStreamInterface,因此可以异步使用。

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% 的规范一致性。支持的编码包括

内置流过滤器

所有 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,所有编解码器实现 EncoderInterfaceDecoderInterfaceCodecInterface。这允许类型提示准确地表达需求。

实现自定义编码

编码器和解码器建立在 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是互逆的。大多数编解码器将需要分别使用编码和解码转换。