talesoft/tale-stream

一个基本的PSR-7和PSR-17兼容的流实用库

0.6.0 2020-01-17 23:27 UTC

This package is auto-updated.

Last update: 2024-09-18 09:57:45 UTC


README

Packagist License CI Coverage

Tale Stream

什么是Tale Stream?

这是PSR-7 Psr\Http\Message\StreamInterface和PSR-17 Psr\Http\Message\StreamFactoryInterface的直接实现。它不添加任何额外的方法,仅提供一些实用的流工厂和一些有用的流迭代器。

它充当稳定流库核心,适用于完整的流库,如套接字实现或文件系统抽象。

安装

composer req talesoft/tale-stream

使用方法

查看函数文件,了解该库所有功能。

流化一切

核心是您可以与Tale\stream函数一起使用的Tale\Stream类。您可以传递任何类型的stream资源,并获得任何目的的PSR-7兼容流。

use function Tale\stream;

$stream = stream(fopen('/some/file', 'rb+'));

if ($stream->isReadable()) {
    $contents = $stream->read(100);
}

if ($stream->isWritable()) {
    $stream->write('Some Content');
}

$stream->close();

为DI容器创建流工厂

use Psr\Http\Message\StreamFactoryInterface;
use Tale\StreamFactory;

$container->add(StreamFactory::class);

// ...

$streamFactory = $container->get(StreamFactoryInterface::class);

$stream = $streamFactory->createStreamFromFile('./some-file.txt', 'rb');

echo $stream; // "<contents of some-file.txt>"

文件流

文件流的工作方式类似于fopen($filename, $mode, $useIncludePath, $context)函数。

use function Tale\stream_file;

$stream = stream_file('./some-file.txt', 'rb');

echo $stream->getContents(); // "<contents of some-file.txt>"

内存流

内存流仅存在于内存中,执行结束后就会消失。这在需要即时创建流的地方非常有用。它们始终可读和可写。

use function Tale\stream_memory;

$stream = stream_memory('Some Content!');

echo $stream->getContents(); // "Some Content!"

临时流

临时流的工作方式类似于内存流,但它们会在某个时候开始将数据交换到文件中,以节省内存。

use function Tale\stream_memory;

$stream = stream_temp('Some Content!', 1024);
// Stream will start swapping after 1024 bytes

输入流

输入流是php://input上的可读文件流。在大多数情况下,这是原始HTTP请求体,对于处理结构化数据格式的API非常有用。

use function Tale\stream_input;

$stream = stream_input();

$data = json_decode($stream->getContents());
echo $data['firstName'];

输出流

输出流是php://output上的可写文件流。这主要是发送到浏览器的输出内容。

use function Tale\stream_output;

$stream = stream_output();

$stream->write('<h1>This will be sent to the browser</h1>');

STDIN流

标准输入流是php://stdin上的可读文件流。例如,来自管道命令的内容。

use function Tale\stream_stdin;

$stream = stream_stdin();

echo $stream->getContents(); // "<piped input>"

STDERR流

标准错误流是php://stderr上的可写文件流。这主要用于在控制台命令中输出错误。

use function Tale\stream_stderr;

$stream = stream_stderr();

$stream->write('Error: Something bad happened');

STDOUT流

标准输出流是php://stdout上的可写文件流。这主要是控制台命令的输出。

use function Tale\stream_stdout;

$stream = stream_stdout();

$stream->write("Working...please wait...\n");

空流

空流不执行任何操作。它仅实现接口。对于避免对可选依赖项进行防御性null检查、抑制某些内容以及测试非常有用。

use function Tale\stream_null;

$stream = stream_null();

echo $stream->read(100); // Will always return an empty string

使用迭代器读取流

ReadIterator将按块逐块读取流(默认块大小为1024)。请注意,这里的所有迭代器都与任何PSR-7流一起工作,而不仅仅是Tale\Stream实例。

use function Tale\stream_memory;
use function Tale\stream_read;

$stream = stream_memory('abcdefg');

$iterator = stream_read($stream, 2); //Chunk size of 2

$chunks = iterator_to_array($iterator);
// You could alternatively iterate the iterator with foreach

dump($chunks); // ['ab', 'cd', 'ef', 'g']

迭代流中的行

LineIterator的工作方式与fgets()不同。虽然fgets()上的块大小限制了行的长度,但LineIterator将仅等待实际行尾,而不关心块大小。

use function Tale\stream_memory;
use function Tale\stream_get_lines;

$stream = stream_memory("Line 1\nLine 2\nLine 3");

$lines = stream_get_lines($stream);

dump(iterator_to_array($lines)); // ["Line 1", "Line 2", "Line 3"]

按分隔符拆分流

SplitIterator是LineIterator之所以能够按此方式工作的原因。它可以按任何长度的任何分隔符拆分流,并且不关心内部读取器的块大小。

use function Tale\stream_memory;
use function Tale\stream_split;

$stream = stream_memory('a,b,c,d');

$items = stream_split($stream, ',');

dump(iterator_to_array($items)); // ['a', 'b', 'c', 'd']

使用迭代器向流写入

WriteIterator是一种将可迭代对象轻松写入流的实用工具。

use function Tale\stream_memory;
use function Tale\stream_write;

function generateLines()
{
    yield "Line 1\n";
    yield "Line 2\n";
    yield "Line 3\n";
}

$stream = stream_memory();

$writer = stream_write($stream, generateLines());
$writtenBytes = $writer->writeAll();

// or use stream_write_all()
$writtenBytes = stream_write_all($stream, generateLines());

// You could also iterate the write to leave place for other actions
// e.g. in async environments

管道流

ReadIterator和WriteIterator的组合提供了一个有效的管道流的高效方法。

use function Tale\stream_memory;
use function Tale\stream_pipe;

$inputStream = stream_memory('Some content');
$outputStream = stream_memory();

$writer = stream_pipe($inputStream, $outputStream);
$writer->writeAll();

// or use stream_pipe_all()
$writtenBytes = stream_pipe_all($inputStream, $outputStream);