Php 从临时文件流,然后在完成时删除?
我通过在PDF文件上运行两个外部Unix工具来编写一个临时文件(基本上我使用QPDF和sed来更改颜色值。不要问):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
//使用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
}