如何在cakephp3中发布包含文件的多部分请求?

w8ntj3qf  于 11个月前  发布在  PHP
关注(0)|答案(1)|浏览(160)

我在cakephp 3中使用http客户端发布文件数据时遇到了麻烦。下面是我使用的代码。
用于在控制器顶部形成数据

use Cake\Http\Client\FormData;

字符串
提交表单前创建fromData对象

$data = new FormData();


在数组中收集整个表单数据

$parametersArray = array(
    'parentTypeId'          => $userDetail->userTypeId,
    'parentId'              => $userDetail->userTypeId,
    'canChangeTrainingPlan' => false,
    'userObject' => array(
        'userTypeId'        => $this->request->data['user_type'],
        'userProfile' => array(
            'firstName'     => $this->request->data['first_name'],
            'lastName'      => $this->request->data['last_name'],
            'dateOfBirth'   => $this->request->data['user_dob'],
            'email'         => $this->request->data['user_email'],
            'phone'         => $this->request->data['user_phone'],
            'profileImage'  => $this->request->data['imageFile']['name'],
            'houseNumber'   => $this->request->data['house_number'],
            'streetNumber'  => $this->request->data['street_number'],
            'locality'      => $this->request->data['user_localty'],
            'landmark'      => $this->request->data['user_landmark'],
            'city'          => $this->request->data['user_city'],
            'state'         => $this->request->data['user_state'],
            'country'       => $this->request->data['user_country'],
            'pincode'       => $this->request->data['user_type'],
        )
    )
);


在第三方API中为post创建最终数组

$finalArray = array(
    'imageFile'  => $this->request->data['imageFile']['name'],
    'postData'   => json_encode($parametersArray),
);


将数据数组添加到formData

$data->add($parametersArray);


现在使用文档https://book.cakephp.org/3.0/en/core-libraries/httpclient.html中提到的Add file代码

// This will append the file to the form data as well.
$file = $data->addFile('imageFile', $this->request->data['imageFile']);
$file->contentId($this->request->data['imageFile']['name']);
$file->disposition('attachment');

// Send the request.
$response = $http->post(
    BASE_API_URL.'user/register/'.$userDetail->id,
    $data,
    ['headers' => ['Content-Type' => $data->contentType()]]
);


现在的问题是,我得到了一些警告file_get_contents()和响应400坏请求从API。
API是工作罚款测试它使用 Postman 。

所需API输入、输出和响应

URL:    {BASE_URL}/user/register/{currentUserId}    
Input:  {currentUserId} the logged in user id
    Form Data with following params:    
    imageFile   the user profile image file selected from PC
    postData    "{
""parentTypeId"":1,
""parentId"":1,
""canChangeTrainingPlan"":false,
""userObject"":{""id"":5,""userTypeId"":3,""userProfile"":{""firstName"":""Jyotsana"",""lastName"":""Arora"",""dateOfBirth"":""1989-07-16"",""email"":""[email protected]"",""phone"":"""",""profileImage"":""<FILE_NAME>"",""houseNumber"":"""",""streetNumber"":"""",""locality"":"""",""landmark"":"""",""city"":"""",""state"":"""",""country"":"""",""pincode"":""160022""}}}
""profileImage"" key must contain the selected File name"
API Params  API must have following parameters: 
    enctype:    multipart/form-data'
    contentType:    false
    processData:    false
    cache:  false
Output:     "User object with complete details:
USER_ID > 0 : Successful Registration
USER_ID = 0 : Current user is not allowed to register this user
USER_ID = -1: Server Error
USER_ID = -2: Current User Id is invalid
USER_ID = -3: Input User object is not correct
USER_ID = -4: Email already exists
USER_ID = -8: Parent Id is invalid"

yeotifhr

yeotifhr1#

你误解了文档,你不能传递文件上传数组,既不能传递给HttpClient::post(),也不能传递给FormData::addFile()。示例显示了如何从请求中传递用户数据,只是演示了如何合理地做到这一点,因为前缀为@的字符串将被解释为本地/远程文件包含路径(这就是为什么在hat部分提到它)。
长话短说,FormData::addFile()只接受文件资源句柄,或者前面有@的文件包含路径(如红色警告框所示,这是不推荐的)。因此,如文档中的第一个示例所示,传递文件句柄应该可以解决生成无效表单数据的问题。

$file = $data->addFile(
    'imageFile',
    fopen($this->request->data['imageFile']['tmp_name'], 'r')
);

字符串
此外,您应该显式地将数据转换为字符串,如示例所示:

$response = $http->post(
    BASE_API_URL.'user/register/'.$userDetail->id,
    (string)$data, // <<< cast data to a string
    ['headers' => ['Content-Type' => $data->contentType()]]
);


另见

*Cookbook > Http Client >手工构建多部分请求体
*API > \Cake\Http\Client\FormData::addFile()

相关问题