安全地存档 guzzle 响应

safely archive guzzle responses

我正在尝试获取一组图像 url 并使用 guzzle 获取它们并将它们添加到 ZipArchive。我过去做过少量有意识的异步编码,但不确定如何在 php 中最好地处理这个问题。

这是我目前的情况:

<?php

$requests = [];
foreach ($urls as $url) {
    $requests[] = new \GuzzleHttp\Psr7\Request('GET', $url);
};

$zip = new ZipArchive();

$client = new \GuzzleHttp\Client();

$pool = new \GuzzleHttp\Pool($client, $requests, [
   'concurrency' => 5,
    'fulfilled' => function ($response) use ($zip) {
        $id = \Rhumsaa\Uuid\Uuid::uuid4()->toString();
        $zip->addFromString($id, (string)$response->getBody());
    },
    'rejected' => function ($reason, $index) {
         // no-op
    }
]);

$pool->promise()->wait();

$zip->close();

因为这些请求将同时发送,我是否需要以某种方式lock/unlock 访问 fulfilled 回调中的 $zip?如果可以,怎么做?

额外的(不相关的)问题:如果不在 url 中,从 $response 中获取适当扩展名的最佳方法是什么?有没有比检查内容类型和使用地图更简洁的方法?例如:

$extensions = [
    'image/png' => '.png',
    'image/jpeg' => '.jpeg',
    'image/gif' => '.gif',
    // etc
];

do I need to somehow lock/unlock access to $zip inside the fulfilled callback?

不,你不知道。承诺是异步解决的,当然,但它都在一个线程中。当你这样做时:

$zip->addFromString($id, (string)$response->getBody());

在将文件添加到 ZIP 存档之前,您正在此处阻止 php。

What's the best way to go about getting the appropriate extension of the fetched image from the $response if it's not in the url?

我认为检查 Content-Type 是正确的方法。你可以这样做:

$contentType = explode(';', $response->getHeaderLine('Content-Type'), 2)[0];
$extensions = [
    'image/png' => '.png',
    'image/jpeg' => '.jpeg',
    'image/gif' => '.gif',
    // etc
];

// check for $extensions[$contentType];