几年前在这里问过类似的问题,但没有答案: Get path of temp file created via fopen('php://temp')
我正在使用Google Cloud Storage并行下载许多大文件,然后将其上传到另一服务。基本上是通过我的服务器B从A转移到C。
在后台,Google的StorageObject-> downloadAsStream()
使用Guzzle通过fopen('php://temp','r+')
获取文件。
我遇到了磁盘空间问题,因为如果在传输过程中引发异常,那么Google的Cloud Storage库不会清除临时文件。 (根据docs,这是预期的行为)。每次重试该脚本都会在我的tmp目录中转储另一个没有清除的巨大文件。
如果Guzzle使用了tmpfile()
,我将能够使用stream_get_meta_data()['uri']
来获取文件路径,但是由于它使用了php://temp
,因此似乎无法使用此选项:
[
"wrapper_type" => "PHP",
"stream_type" => "TEMP",
"mode" => "w+b",
"unread_bytes" => 0,
"seekable" => true,
"uri" => "php://temp", // <<<<<<<< grr.
]
所以:有没有人知道一种获取fopen('php://temp')
创建的临时文件名的方法,以便我可以执行手动清理?
更新:
看来这是不可能的。希望GCS将更新其库以更改临时文件的生成方式。在此之前,我将使用以下清理代码:
public function cleanTempDir(int $timeout = 7200) {
foreach (glob(sys_get_temp_dir()."/php*") as $f) {
if (is_writable($f) && filemtime($f) < (time() - $timeout))
unlink($f);
}
}
答案 0 :(得分:0)
很可能是系统配置的临时目录,您可以通过sys_get_temp_dir来获得。
请注意,这只会在需要时保存到文件,并且可以驻留在内存中。 https://www.php.net/manual/en/wrappers.php.php
编辑:确定,文件已创建。然后,您可能可以在流句柄上使用stream_get_meta_data从流中获取该信息。
答案 1 :(得分:0)
此处提供Google Cloud Platform支持!
目前,使用php Cloud Storage库无法获得使用downloadAsStream()方法创建的临时文件名。因此,我已代表您创建了功能请求,您可以按照here进行操作。
作为解决方法,您可以手动删除文件,可以使用以下命令获取临时文件名:
$filename = shell_exec('ls -lt | awk 'NR==2' | cut -d: -f2 | cut -d " " -f2');
此后,$ filename将包含最后一个修改的文件名,该文件名将失败,并且您希望将其删除。使用文件名,您现在可以继续删除它。
请注意,执行该功能之前,您必须位于php:// temp文件夹中。
答案 2 :(得分:0)
如下所示的方法可以解决问题:
use Google\Cloud\Storage\StorageClient;
$client = new StorageClient;
$tempStream = tmpfile();
$tempFile = stream_get_meta_data($tempStream)['uri'];
try {
$stream = $client->bucket('my-bucket')
->object('my-big-ol-file')
->downloadAsStream([
'restOptions' => [
'sink' => $tempStream
]
]);
} catch (\Exception $ex) {
unlink($tempFile);
}
通过restOptions
选项,您可以通过命令代理基本的HTTP 1.1传输(默认情况下为Guzzle)。我很抱歉没有对此进行明确记录,但希望对您有所帮助!