从临时文件流,然后在完成后删除?

时间:2017-08-16 19:22:05

标签: php stream php-7 guzzle guzzle6

我正在通过在PDF文件上运行几个外部Unix工具来编写一个临时文件(基本上我正在使用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文件作为字符串读取,删除它,然后将字符串移交给另一个类进行处理。

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

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

我一直在模糊地考虑滚动自己的SelfDestructingFileStream,但这看起来有点矫枉过正,我想我可能会遗漏一些东西。

1 个答案:

答案 0 :(得分:1)

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

<?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,然后当文件超出范围时文件将自行删除。