使用php将分块文件上传到s3

问题描述

我有一个 PHP 脚本,我将用户上传文件存储在 tmp 文件夹中,然后将其移动到 s3。我还检查他们输入的电子邮件数据库中是否有效。我正在使用分块,以便大文件可以快速上传到服务器。我的 post_max_size 是 8M,但是我只能上传很小的文件

例如,如果我上传一个 7M 的文件,我会收到一条我设置的警报,指出文件过大。仅当文件大小大于 8M 时才应显示此警报。如果我上传 1 KB 文件,它会成功上传文件。我做错了什么吗?我对 PHP 还很陌生,所以我很感激你的帮助!

这是我对 PHP 文件的 ajax 调用

class AuthorSerializer(serializers.ModelSerializer):
    general = serializers.DictField(write_only=True)
    details = serializers.ListField(write_only=True)

    class Meta:
        model = Author
        fields = [
            "id","general","details",]

    def create(self,validated_data):
        author_data = {}
        author_data['first_name'] = validated_data['general']['name']
        author_data['last_name'] = validated_data['general']['surname']
        author_data['birth_year'] = validated_data['details'][0]

        author = Author.objects.create(**author_data) 
        return author_data 

    def to_representation(self,instance):

        final_representation = OrderedDict()

        final_representation["id"] = instance.id
        final_representation["general"] = {}
        final_representation["general"]["name"] = instance.first_name
        final_representation["general"]["surname"] = instance.last_name

        final_representation["details"] = [instance.birth_year]
        
        return final_representation

这是我的 dbSystem.PHP 文件

$.ajax({
    type: "POST",url: "../FileDrop/dbSystem.PHP",cache: false,processData: false,contentType: false,data: formData,success: function(result) {
        result = JSON.parse(result);
        if (result.validity === "valid emails") {
            resetInputs();
            location.reload();
            $(".outputDiv").show();
        }
        else if (result.validity === "invalid emails") {
            var tagsBrackets = result.emails.toString().replace(/[\[\]']+/g,'');
            var tagsQuotes = tagsBrackets.replace(/['"]+/g,'');
            var tagsInvalid = tagsQuotes.replace(/,/g,",");
            $('#alertModal').modal({show:true});
            document.getElementById('invalid').textContent = tagsInvalid;
        }
        else {
            $('#alertModalFile').modal({show:true});
            document.getElementById('userFile').value = null;
        }
    }
});

解决方法

ini_get('post_max_size') 可以(并且将会)返回对人类友好的值。因此,您最终将比较整数文件大小值与字符串值(在您的情况下为 8M)。还有9000 > '8M'...

更新: 无需显式使用 PHP 配置值 post_max_sizeupload_max_filesize,因为:

  1. 如果超过 post_max_size 值,$_FILES 数组将为空,并生成警告,例如:

Warning: POST Content-Length of 3414 bytes 超出 Unknown on line 2048 bytes 的限制

  1. 如果超过 upload_max_filesize 值,'error' 数组中对应的 $_FILES 字段将包含 UPLOAD_ERR_INI_SIZE 值,例如:

array(1) { ["name"]=> array(5) { ["name"]=> string(12) "filename.ext" ["type"]=> string(0) "" [ "tmp_name"]=> string(0) "" ["error"]=> int(1) ["size"]=> int(0) } }

以上都意味着如果有一个非空的$_FILES数组可用并且错误字段的值为UPLOAD_ERR_OK,则可以确定上传成功并且配置值也得到遵守.

在您的情况下,这转化为条件 if ($_FILES['file']['size'] <= ini_get('post_max_size')) ... 不仅不正确(将整数文件大小(例如 9000)与可能的非整数字符串(例如 '8M')进行比较),而且根本不需要。

,

我不确定这有多相关,但我注意到您没有在任何地方指定数据类型为“multipart/form-data”。我一直认为除非指定,否则文件上传将无法正常工作。

本身也不相关,但我看到您正在使用 jQuery。我建议远离它并使用本机 fetch API。这是一种更清洁、更现代的解决方案。