Google Cloud Storage获取临时文件名(使用fopen('php:// temp'))

时间:2019-07-12 19:02:52

标签: php google-cloud-storage guzzle guzzle6

  

几年前在这里问过类似的问题,但没有答案:   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);

    }

}

3 个答案:

答案 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)。我很抱歉没有对此进行明确记录,但希望对您有所帮助!