Yurunsoft / Guzzle-Swoole

让基于 Guzzle 的项目完美无缝兼容 Swoole 协程,支持:Guzzle、Elasticsearch client——来自宇润 PHP 全家桶
MIT License
161 stars 21 forks source link

HTTP error: Invalid argument supplied for foreach() #18

Closed DlenoDing closed 4 years ago

DlenoDing commented 4 years ago

[ERROR] Coroutine internal error: Error executing "PutObject" on "**"; AWS HTTP error: Invalid argument supplied for foreach()

swoft2.X框架里,使用的进程池,功能为上传文件到AWS存储桶
AwsClient.php::

<?php declare(strict_types=1);
/**
 * This file is part of Swoft.
 *
 * @link     https://swoft.org
 * @document https://swoft.org/docs
 * @contact  group@swoft.org
 * @license  https://github.com/swoft-cloud/swoft/blob/master/LICENSE
 */

namespace App\Common;

use Aws\S3\ObjectUploader;
use Swoft\Bean\Annotation\Mapping\Bean;
use Aws\S3\S3Client;

/**
 * Class AwsS3Client
 *
 * @package App\Common
 * @Bean()
 */
class AwsS3Client
{
    private $client = null;

    /**
     * init
     * AwsS3Client constructor.
     */
    public function __construct()
    {
        //设置HOME环境变量,aws取key配置是根据环境变量取的
        putenv('HOME='.alias('@base'));
        //也可以设置 AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY 环境变量,sdk优先取这两个环境变量
        //putenv('AWS_ACCESS_KEY_ID=XXXXXX');
        //putenv('AWS_SECRET_ACCESS_KEY=XXXXXX');
        //创建连接客户端
        $config = config('aws');
        $this->client = new S3Client($config);
    }

    /**
     * 上传文件
     * @param $fileKey
     * @param $fileSource
     * @param string $acl
     * @return mixed
     */
    public function uploadFile($fileKey, $fileSource, $acl = 'public-read', $options = [])
    {
        $fileParse  = parse_url($fileSource);
        //后缀问题
        $suffix     = explode('.', $fileParse['path']);
        if (count($suffix) > 1) {
            $suffix = '.'.$suffix[count($suffix)-1];
        } else {
            $suffix = '';
        }

        $fileKey    = $fileKey.$suffix;

        $context = array(
            'http' => array(
                'timeout' => 180, //设置一个超时时间,单位为秒
            )
        );
        $context = stream_context_create($context);

        try{
            $fileSource = fopen($fileSource, 'r', false, $context);
            if (!$fileSource) {
                return false;
            }
        } catch (\Exception $e) {
            return false;
        }

        $uploader = new ObjectUploader(
            $this->client,
            config('aws.Bucket'),
            $fileKey,
            $fileSource,
            $acl,
            $options
        );
        $result = $uploader->upload();
        if (!empty($result) && $result["@metadata"]["statusCode"] == '200') {
            return $result["ObjectURL"];
        }

        return false;
    }
}

调用(使用协程go方式调用):
//图片可以访问并打开,但会报错
$img     = $this->awsS3Client->uploadFile('123', 'http://p-cdn.upliveapp.com/uplive/p/u/2020/7/5/27d47fc6-dddd-4bf6-a60b-6926fe4a1ac7.jpg');

//这张图片也可以访问,同样的调用,可以正常执行
//http://p.cdn.upliveapps.com/uplive/p/u/2018/2/12/28527957_1518366217748.jpg
Yurunsoft commented 4 years ago

经测试是一个 Warning,实际文件已经上传成功的。 问题出在依赖的YurunHttp中,已经修复:https://github.com/Yurunsoft/YurunHttp/commit/e8e604b79e434bf434d6ab4643e9e69458548cf7

可以在composer.jsonrequire中加入: "yurunsoft/yurun-http": "dev-dev" 然后更新一下后尝试问题是否已经解决,如果已经解决晚点会发布一个版本