从临时文件流式传输,完成后删除?

Stream from a temporary file, then delete when finished?

我正在通过 运行 几个外部 Unix 工具在 PDF 文件上编写一个临时文件(基本上我使用 QPDF 和 sed 来改变颜色值。不要问。):

// Uncompress PDF using QPDF (doesn't read from stdin, so needs tempfile.)
$compressed_file_path = tempnam(sys_get_temp_dir(), 'cruciverbal');
file_put_contents($compressed_file_path, $response->getBody());  
$uncompressed_file_path = tempnam(sys_get_temp_dir(), 'cruciverbal');
$command = "qpdf --qdf --object-streams=disable '$compressed_file_path' '$uncompressed_file_path'";
exec($command, $output, $return_value);

// Run through sed (could do this bit with streaming stdin/stdout)
$fixed_file_path = tempnam(sys_get_temp_dir(), 'cruciverbal');
$command = "sed s/0.298039215/0.0/g < '$uncompressed_file_path' > '$fixed_file_path'";
exec($command, $output, $return_value);

所以,当这完成后,我在 $fixed_file_path 的磁盘上留下了一个临时文件。 (注意:虽然我可以在没有临时文件的情况下在内存中执行整个 sed 流程,但 QPDF 实用程序 requires an actual file as input 有充分的理由。)

在我现有的流程中,然后我将整个 $fixed_file_path 文件作为一个字符串读入,将其删除,然后将该字符串交给另一个 class 去处理。

我现在想将最后一部分更改为使用 PSR-7 流,即 \Guzzle\Psr7\Stream 对象。我认为它会更节省内存(我可能会同时播放其中的一些)并且最终需要成为一个流。

但是,我不确定当(第三方)class 我将流交给它时我将如何删除临时文件。有没有一种方法可以说“......并在你完成后删除它”?或者以其他方式自动清理我的临时文件,而无需手动跟踪它们?

我一直在模糊地考虑推出自己的 SelfDestructingFileStream,但这似乎有些过分,我想我可能会遗漏一些东西。

听起来你想要的是这样的:

<?php

class TempFile implements \Psr\Http\Message\StreamInterface {

    private $resource;

    public function __construct() {
        $this->resource = tmpfile();
    }

    public function __destruct() {
        $this->close();
    }

    public function getFilename() {
        return $this->getMetadata('uri');
    }

    public function getMetadata($key = null) {
        $data = stream_get_meta_data($this->resource);
        if($key) {
            return $data[$key];
        }
        return $data;
    }

    public function close() {
        fclose($this->resource);
    }

    // TODO: implement methods from https://github.com/php-fig/http-message/blob/master/src/StreamInterface.php
}

让 QPDF 写入 $tmpFile->getFilename(),然后您可以将整个对象传递给您的 Guzzle/POST,因为它符合 PSR-7,然后文件将在超出范围时自行删除。