Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 从临时文件流,然后在完成时删除?_Php_Stream_Php 7_Guzzle_Guzzle6 - Fatal编程技术网

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

Php 从临时文件流,然后在完成时删除?,php,stream,php-7,guzzle,guzzle6,Php,Stream,Php 7,Guzzle,Guzzle6,我通过在PDF文件上运行两个外部Unix工具来编写一个临时文件(基本上我使用QPDF和sed来更改颜色值。不要问): //使用QPDF解压PDF(不从stdin读取,因此需要tempfile。) $compressed_file_path=tempnam(sys_get_temp_dir(),'crossiver'); 文件内容($compressed_file_path,$response->getBody()); $uncompressed_file_path=tempnam(sys_get

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

//使用QPDF解压PDF(不从stdin读取,因此需要tempfile。)
$compressed_file_path=tempnam(sys_get_temp_dir(),'crossiver');
文件内容($compressed_file_path,$response->getBody());
$uncompressed_file_path=tempnam(sys_get_temp_dir(),'crossiver');
$command=“qpdf--qdf--object streams=禁用“$compressed\u file\u path”“$uncompressed\u file\u path”“;
exec($command,$output,$return_value);
//通过sed运行(可以通过流式stdin/stdout执行此位)
$fixed_file_path=tempnam(sys_get_temp_dir(),'crossiver');
$command=“sed s/0.298039215/0.0/g<'$uncompressed_file_path'>'$fixed_file_path';
exec($command,$output,$return_value);
因此,当这项工作完成后,磁盘上剩下一个临时文件,位于
$fixed\u file\u path
。(注意:虽然我可以在不使用tempfile的情况下完成整个
sed
流程,但QPDF实用程序是有充分理由的。)

在我现有的过程中,我将整个
$fixed_file_path
文件作为字符串读入,删除它,然后将字符串交给另一个类处理

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

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


我一直在模糊地考虑使用我自己的
自毁文件流
,但这似乎有些过分,我想我可能遗漏了一些东西。

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

<?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
}

shell\u exec
将返回命令的完整输出。为什么要输出到一个文件?@mpen嗯,基本上是因为一开始这是一个又快又脏的过程。我现在正在尝试清理它,我肯定会考虑直接从流程中读取
sed
的结果。然而,我似乎记得前面的QPDF处理流媒体的效果并不好,可能是因为PDF没有那么“流畅”(它们没有按照流媒体的有用顺序编写),所以我已经有了一个临时文件。你通过添加
\Guzzle\Psr7\Stream
引入了开销,除非你已经有了可以使用Guzzle/Psr7流的类。如果使用正确的方法,PHP内置了对流的支持。QPDF可能需要在开始处理之前将整个文件缓冲到内存中,并且在完全完成之前可能不会输出任何内容,但您仍然可以在PHP端使用流。如果它利用了它们,那就太好了!节省更多内存。如果没有,我认为这不会有任何伤害。@mpen我确实有使用PSR7流的类;该文件最终将被发送到一个Guzzle POST请求,因此我认为作为一个流,它的内存效率会更高。是的;QPDF需要在处理它之前读入整个内容,所以它不会从stdin.Oh.中获取。但是您编写了
<'$uncompressed\u file\u path'
。它通过stdin发送文件。那不行吗?如果它只读取和写入文件,我认为您必须创建一个
tmpfile()
,然后在完成后取消链接()。据我所知,没有办法让它自动删除自己。您可以创建一个类来包装它,并在其中添加析构函数(
\uu destruct
)。我使用handy来避免手动实现其他流方法。@MattGibson噢,很好。我不知道这个特点。谢谢分享:-DNo问题。我很高兴能得到一些保证,我模糊的计划正沿着大致合理的方向发展。。。
<?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
}