0 关注者

类 yii\web\MultipartFormDataParser

继承yii\web\MultipartFormDataParser » yii\base\BaseObject
实现yii\base\Configurable, yii\web\RequestParserInterface
可用版本2.0.10
源代码 https://github.com/yiisoft/yii2/blob/master/framework/web/MultipartFormDataParser.php

MultipartFormDataParser 解析以 'multipart/form-data' 编码的内容。

此解析器提供非 POST 请求(例如:使用 'PUT' 请求方法的请求)上 'multipart/form-data' 处理的回退。

为了启用此解析器,您应该配置 yii\web\Request::$parsers,如下所示

return [
    'components' => [
        'request' => [
            'parsers' => [
                'multipart/form-data' => 'yii\web\MultipartFormDataParser'
            ],
        ],
        // ...
    ],
    // ...
];

此解析器的 parse() 方法会自动将 $_FILES 中填充从原始主体解析的文件。

注意: 由于这是一个请求解析器,它会在 yii\web\Request::getBodyParams() 上初始化 $_FILES 值。在调用此方法之前,即使请求主体中包含提交的文件,$_FILES 数组也会保持为空。如果您使用此解析器,请确保在尝试获取上传文件之前已请求主体参数。

使用示例

use yii\web\UploadedFile;

$restRequestData = Yii::$app->request->getBodyParams();
$uploadedFile = UploadedFile::getInstancesByName('photo');

$model = new Item();
$model->populate($restRequestData);
copy($uploadedFile->tempName, '/path/to/file/storage/photo.jpg');

注意: 尽管此解析器完全模拟了 $_FILES 的常规结构,但通过 tmp_name 键可用的相关临时文件将不会被 PHP 识别为上传文件。因此,诸如 is_uploaded_file()move_uploaded_file() 之类的函数将在它们上失败。

公共属性

隐藏继承的属性

属性 类型 描述 定义于
$force boolean 是否即使在 'POST' 请求和 $_FILES 已填充的情况下也解析原始主体。默认情况下,此选项被禁用,为 'POST' 请求节省了性能,这些请求已由 PHP 自动处理。 > 注意:如果启用此选项,$_FILES 的值将在每次解析时重置。 yii\web\MultipartFormDataParser
$uploadFileMaxCount integer 最大上传文件数。 yii\web\MultipartFormDataParser
$uploadFileMaxSize integer 上传文件最大大小,以字节为单位。 yii\web\MultipartFormDataParser

公共方法

隐藏继承的方法

方法 描述 定义于
__call() 调用非类方法的命名方法。 yii\base\BaseObject
__construct() 构造函数。 yii\base\BaseObject
__get() 返回对象属性的值。 yii\base\BaseObject
__isset() 检查属性是否已设置,即定义且不为空。 yii\base\BaseObject
__set() 设置对象属性的值。 yii\base\BaseObject
__unset() 将对象属性设置为 null。 yii\base\BaseObject
canGetProperty() 返回一个值,指示是否可以读取属性。 yii\base\BaseObject
canSetProperty() 返回一个值,指示是否可以设置属性。 yii\base\BaseObject
className() 返回此类的完全限定名称。 yii\base\BaseObject
getUploadFileMaxCount() yii\web\MultipartFormDataParser
getUploadFileMaxSize() yii\web\MultipartFormDataParser
hasMethod() 返回一个值,指示是否定义了方法。 yii\base\BaseObject
hasProperty() 返回一个值,指示是否定义了属性。 yii\base\BaseObject
init() 初始化对象。 yii\base\BaseObject
parse() 解析 HTTP 请求主体。 yii\web\MultipartFormDataParser
setUploadFileMaxCount() yii\web\MultipartFormDataParser
setUploadFileMaxSize() yii\web\MultipartFormDataParser

属性详细信息

隐藏继承的属性

$force 公共属性 (从版本 2.0.13 开始可用)

是否即使在 'POST' 请求和 $_FILES 已填充的情况下也解析原始主体。默认情况下,此选项被禁用,为 'POST' 请求节省了性能,这些请求已由 PHP 自动处理。 > 注意:如果启用此选项,$_FILES 的值将在每次解析时重置。

public boolean $force false
$uploadFileMaxCount 公共属性

最大上传文件数。

$uploadFileMaxSize 公共属性

上传文件最大大小,以字节为单位。

方法详细信息

隐藏继承的方法

__call() 公共方法

定义于: yii\base\BaseObject::__call()

调用非类方法的命名方法。

不要直接调用此方法,因为它是一个 PHP 魔术方法,当调用未知方法时会隐式调用。

public mixed __call ( $name, $params )
$name string

方法名

$params array

方法参数

返回值 mixed

方法返回值

抛出 yii\base\UnknownMethodException

调用未知方法时

                public function __call($name, $params)
{
    throw new UnknownMethodException('Calling unknown method: ' . get_class($this) . "::$name()");
}

            
__construct() 公共方法

定义于: yii\base\BaseObject::__construct()

构造函数。

默认实现执行两件事

  • 使用给定的配置 $config 初始化对象。
  • 调用 init()

如果在子类中重写此方法,建议

  • 构造函数的最后一个参数是一个配置数组,这里类似于 $config
  • 在构造函数的末尾调用父类的实现。
public void __construct ( $config = [] )
$config array

用于初始化对象属性的键值对。

                public function __construct($config = [])
{
    if (!empty($config)) {
        Yii::configure($this, $config);
    }
    $this->init();
}

            
__get() 公共方法

定义在: yii\base\BaseObject::__get()

返回对象属性的值。

不要直接调用此方法,因为它是一个 PHP 魔术方法,在执行 $value = $object->property; 时将被隐式调用。

另请参阅 __set().

public mixed __get ( $name )
$name string

属性名称

返回值 mixed

属性值

抛出 yii\base\UnknownPropertyException

如果属性未定义

抛出 yii\base\InvalidCallException

如果属性是只写

                public function __get($name)
{
    $getter = 'get' . $name;
    if (method_exists($this, $getter)) {
        return $this->$getter();
    } elseif (method_exists($this, 'set' . $name)) {
        throw new InvalidCallException('Getting write-only property: ' . get_class($this) . '::' . $name);
    }
    throw new UnknownPropertyException('Getting unknown property: ' . get_class($this) . '::' . $name);
}

            
__isset() 公共方法

定义在: yii\base\BaseObject::__isset()

检查属性是否已设置,即定义且不为空。

不要直接调用此方法,因为它是一个 PHP 魔术方法,在执行 isset($object->property) 时将被隐式调用。

请注意,如果属性未定义,将返回 false。

另请参阅 https://php.ac.cn/manual/en/function.isset.php.

public boolean __isset ( $name )
$name string

属性名称或事件名称

返回值 boolean

命名的属性是否已设置(不为 null)。

                public function __isset($name)
{
    $getter = 'get' . $name;
    if (method_exists($this, $getter)) {
        return $this->$getter() !== null;
    }
    return false;
}

            
__set() 公共方法

定义在: yii\base\BaseObject::__set()

设置对象属性的值。

不要直接调用此方法,因为它是一个 PHP 魔术方法,在执行 $object->property = $value; 时将被隐式调用。

另请参阅 __get().

public void __set ( $name, $value )
$name string

属性名称或事件名称

$value mixed

属性值

抛出 yii\base\UnknownPropertyException

如果属性未定义

抛出 yii\base\InvalidCallException

如果属性是只读

                public function __set($name, $value)
{
    $setter = 'set' . $name;
    if (method_exists($this, $setter)) {
        $this->$setter($value);
    } elseif (method_exists($this, 'get' . $name)) {
        throw new InvalidCallException('Setting read-only property: ' . get_class($this) . '::' . $name);
    } else {
        throw new UnknownPropertyException('Setting unknown property: ' . get_class($this) . '::' . $name);
    }
}

            
__unset() 公共方法

定义在: yii\base\BaseObject::__unset()

将对象属性设置为 null。

不要直接调用此方法,因为它是一个 PHP 魔术方法,在执行 unset($object->property) 时将被隐式调用。

请注意,如果属性未定义,此方法将不做任何事情。如果属性是只读,它将抛出异常。

另请参阅 https://php.ac.cn/manual/en/function.unset.php.

public void __unset ( $name )
$name string

属性名称

抛出 yii\base\InvalidCallException

如果属性是只读。

                public function __unset($name)
{
    $setter = 'set' . $name;
    if (method_exists($this, $setter)) {
        $this->$setter(null);
    } elseif (method_exists($this, 'get' . $name)) {
        throw new InvalidCallException('Unsetting read-only property: ' . get_class($this) . '::' . $name);
    }
}

            
canGetProperty() 公共方法

定义在: yii\base\BaseObject::canGetProperty()

返回一个值,指示是否可以读取属性。

如果属性可读,则

  • 该类具有与指定名称关联的 getter 方法(在这种情况下,属性名称不区分大小写);
  • 该类具有与指定名称相同的成员变量(当 $checkVars 为 true 时);

另请参阅 canSetProperty().

public boolean canGetProperty ( $name, $checkVars true )
$name string

属性名称

$checkVars boolean

是否将成员变量视为属性

返回值 boolean

属性是否可读

                public function canGetProperty($name, $checkVars = true)
{
    return method_exists($this, 'get' . $name) || $checkVars && property_exists($this, $name);
}

            
canSetProperty() 公共方法

定义在: yii\base\BaseObject::canSetProperty()

返回一个值,指示是否可以设置属性。

如果属性可写,则

  • 该类具有与指定名称关联的 setter 方法(在这种情况下,属性名称不区分大小写);
  • 该类具有与指定名称相同的成员变量(当 $checkVars 为 true 时);

另请参阅 canGetProperty().

public boolean canSetProperty ( $name, $checkVars true )
$name string

属性名称

$checkVars boolean

是否将成员变量视为属性

返回值 boolean

属性是否可写

                public function canSetProperty($name, $checkVars = true)
{
    return method_exists($this, 'set' . $name) || $checkVars && property_exists($this, $name);
}

            
className() 公共静态方法
自 2.0.14 起已弃用。在 PHP >=5.5 上,请使用 ::class 代替。

定义在: yii\base\BaseObject::className()

返回此类的完全限定名称。

public static string className ( )
返回值 string

此类的完全限定名称。

                public static function className()
{
    return get_called_class();
}

            
getUploadFileMaxCount() 公共方法

public integer getUploadFileMaxCount ( )
返回值 integer

最大上传文件数。

                public function getUploadFileMaxCount()
{
    if ($this->_uploadFileMaxCount === null) {
        $this->_uploadFileMaxCount = (int)ini_get('max_file_uploads');
    }
    return $this->_uploadFileMaxCount;
}

            
getUploadFileMaxSize() 公共方法

public integer getUploadFileMaxSize ( )
返回值 integer

上传文件最大大小,以字节为单位。

                public function getUploadFileMaxSize()
{
    if ($this->_uploadFileMaxSize === null) {
        $this->_uploadFileMaxSize = $this->getByteSize(ini_get('upload_max_filesize'));
    }
    return $this->_uploadFileMaxSize;
}

            
hasMethod() 公共方法

定义在: yii\base\BaseObject::hasMethod()

返回一个值,指示是否定义了方法。

默认实现是调用 php 函数 method_exists()。当您实现 php 魔术方法 __call() 时,您可以覆盖此方法。

public boolean hasMethod ( $name )
$name string

方法名

返回值 boolean

方法是否已定义

                public function hasMethod($name)
{
    return method_exists($this, $name);
}

            
hasProperty() 公共方法

定义在: yii\base\BaseObject::hasProperty()

返回一个值,指示是否定义了属性。

如果属性已定义,则

  • 如果类包含与指定名称关联的 getter 或 setter 方法(在本例中,属性名称不区分大小写);
  • 该类具有与指定名称相同的成员变量(当 $checkVars 为 true 时);

另请参阅

public boolean hasProperty ( $name, $checkVars true )
$name string

属性名称

$checkVars boolean

是否将成员变量视为属性

返回值 boolean

属性是否已定义

                public function hasProperty($name, $checkVars = true)
{
    return $this->canGetProperty($name, $checkVars) || $this->canSetProperty($name, false);
}

            
init() 公共方法

定义于: yii\base\BaseObject::init()

初始化对象。

此方法在构造函数结束时调用,在对象使用给定的配置初始化后调用。

public void init ( )

                public function init()
{
}

            
parse() 公共方法

解析 HTTP 请求主体。

public array parse ( $rawBody, $contentType )
$rawBody string

原始 HTTP 请求体。

$contentType string

为请求体指定的 Content-Type。

返回值 array

从请求体解析的参数

                public function parse($rawBody, $contentType)
{
    if (!$this->force) {
        if (!empty($_POST) || !empty($_FILES)) {
            // normal POST request is parsed by PHP automatically
            return $_POST;
        }
    } else {
        $_FILES = [];
    }
    if (empty($rawBody)) {
        return [];
    }
    if (!preg_match('/boundary="?(.*)"?$/is', $contentType, $matches)) {
        return [];
    }
    $boundary = trim($matches[1], '"');
    $bodyParts = preg_split('/\\R?-+' . preg_quote($boundary, '/') . '/s', $rawBody);
    array_pop($bodyParts); // last block always has no data, contains boundary ending like `--`
    $bodyParams = [];
    $filesCount = 0;
    foreach ($bodyParts as $bodyPart) {
        if (empty($bodyPart)) {
            continue;
        }
        list($headers, $value) = preg_split('/\\R\\R/', $bodyPart, 2);
        $headers = $this->parseHeaders($headers);
        if (!isset($headers['content-disposition']['name'])) {
            continue;
        }
        if (isset($headers['content-disposition']['filename'])) {
            // file upload:
            if ($filesCount >= $this->getUploadFileMaxCount()) {
                continue;
            }
            $fileInfo = [
                'name' => $headers['content-disposition']['filename'],
                'type' => ArrayHelper::getValue($headers, 'content-type', 'application/octet-stream'),
                'size' => StringHelper::byteLength($value),
                'error' => UPLOAD_ERR_OK,
                'tmp_name' => null,
            ];
            if ($fileInfo['size'] > $this->getUploadFileMaxSize()) {
                $fileInfo['error'] = UPLOAD_ERR_INI_SIZE;
            } else {
                $tmpResource = tmpfile();
                if ($tmpResource === false) {
                    $fileInfo['error'] = UPLOAD_ERR_CANT_WRITE;
                } else {
                    $tmpResourceMetaData = stream_get_meta_data($tmpResource);
                    $tmpFileName = $tmpResourceMetaData['uri'];
                    if (empty($tmpFileName)) {
                        $fileInfo['error'] = UPLOAD_ERR_CANT_WRITE;
                        @fclose($tmpResource);
                    } else {
                        fwrite($tmpResource, $value);
                        rewind($tmpResource);
                        $fileInfo['tmp_name'] = $tmpFileName;
                        $fileInfo['tmp_resource'] = $tmpResource; // save file resource, otherwise it will be deleted
                    }
                }
            }
            $this->addFile($_FILES, $headers['content-disposition']['name'], $fileInfo);
            $filesCount++;
        } else {
            // regular parameter:
            $this->addValue($bodyParams, $headers['content-disposition']['name'], $value);
        }
    }
    return $bodyParams;
}

            
setUploadFileMaxCount() 公共方法

public void setUploadFileMaxCount ( $uploadFileMaxCount )
$uploadFileMaxCount integer

最大上传文件数。

                public function setUploadFileMaxCount($uploadFileMaxCount)
{
    $this->_uploadFileMaxCount = $uploadFileMaxCount;
}

            
setUploadFileMaxSize() 公共方法

public void setUploadFileMaxSize ( $uploadFileMaxSize )
$uploadFileMaxSize integer

上传文件最大大小,以字节为单位。

                public function setUploadFileMaxSize($uploadFileMaxSize)
{
    $this->_uploadFileMaxSize = $uploadFileMaxSize;
}