You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用MS Graph PHP SDK V2下载文件?V1迁移遇Stream调用错误

Microsoft Graph PHP SDK V2 文件下载实现

问题背景

在SDK V1中,可通过以下代码直接下载文件到指定路径:

$this->graph->createRequest('GET', '/drives/' . $driveId . '/items/' . $itemId . '/content')->download($path);

升级到V2版本后,原方法不再适用,调用content()->get()返回Http\Promise\FulfilledPromise对象(内部包裹GuzzleHttp\Psr7\Stream),调用getBody()时出现错误:Call to undefined method GuzzleHttp\Psr7\Stream::getBody()。

正确实现方法

方式1:同步下载(代码直观,推荐)

通过wait()解析Promise获取Stream对象,直接写入文件:

$tokenRequestContext = new \Microsoft\Kiota\Authentication\Oauth\ClientCredentialContext(
    config('graphapi.azure_tenant_id'),
    config('graphapi.azure_client_id'),
    config('graphapi.azure_client_secret')
);

$graphServiceClient = new \Microsoft\Graph\GraphServiceClient($tokenRequestContext);

// 获取文件流(wait()解析Promise得到Stream对象)
$fileStream = $graphServiceClient->drives()
    ->byDriveId(config('graphapi.attachments_drive_id'))
    ->items()
    ->byDriveItemId('<drive_item_id>')
    ->content()
    ->get()
    ->wait();

// 小文件:直接写入
file_put_contents('test.txt', $fileStream);

// 大文件:使用流复制更高效(避免内存占用过高)
// $destStream = fopen('test.txt', 'wb');
// stream_copy_to_stream($fileStream, $destStream);
// fclose($destStream);

方式2:异步处理

保留Promise异步逻辑,直接操作Stream对象:

$tokenRequestContext = new \Microsoft\Kiota\Authentication\Oauth\ClientCredentialContext(
    config('graphapi.azure_tenant_id'),
    config('graphapi.azure_client_id'),
    config('graphapi.azure_client_secret')
);

$graphServiceClient = new \Microsoft\Graph\GraphServiceClient($tokenRequestContext);

$downloadPromise = $graphServiceClient->drives()
    ->byDriveId(config('graphapi.attachments_drive_id'))
    ->items()
    ->byDriveItemId('<drive_item_id>')
    ->content()
    ->get();

$downloadPromise->then(
    function (\GuzzleHttp\Psr7\Stream $fileStream) {
        // 写入文件
        file_put_contents('test.txt', $fileStream);
        
        // 大文件推荐用流复制
        // $dest = fopen('test.txt', 'wb');
        // stream_copy_to_stream($fileStream, $dest);
        // fclose($dest);
    },
    function (\Exception $e) {
        echo "下载失败:" . $e->getMessage();
    }
);

// 异步模式下需确保进程不提前退出,执行wait()阻塞等待完成
// $downloadPromise->wait();

错误原因说明

之前的代码错误在于:Promise解析后的结果本身就是GuzzleHttp\Psr7\Stream类型的响应体流,无需再调用getBody()方法,直接对该Stream对象进行读取或写入操作即可。

内容的提问来源于stack exchange,提问作者Tom Vaughan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 17:43:17