Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何设置多个内容类型?_Php_Curl - Fatal编程技术网

Php 如何设置多个内容类型?

Php 如何设置多个内容类型?,php,curl,Php,Curl,如何设置多个内容类型?我必须向请求主体传递一个数组。该数组包含一个文本和一个二进制图像 curl_setopt($apiCon, CURLOPT_POSTFIELDS, array( 'status' => rawurlencode($status), 'photo' => $photoInBinary )); curl_setopt($apiCon, CURLOPT_HTTPHEADER, array( 'Host: api.mixi-platform.c

如何设置多个内容类型?我必须向请求主体传递一个数组。该数组包含一个文本和一个二进制图像

curl_setopt($apiCon, CURLOPT_POSTFIELDS, array(
    'status' => rawurlencode($status), 
    'photo' => $photoInBinary
));
curl_setopt($apiCon, CURLOPT_HTTPHEADER, array(
    'Host: api.mixi-platform.com', 
    'Authorization: OAuth ' . $accessToken, 
    'Content-Type: multipart/form-data'
));
问题是主机不理解图像的格式,所以我需要传递更多的内容类型“image/jpg”,但我不知道放在哪里

上面的代码可以工作,但它只发布状态

更新: 好的,我的目标是在社交网络页面上发布带有照片的状态

有关更多信息,请阅读以下内容:

这是我的密码。它可以工作,但只发布状态,而不是照片

    $apiCon = curl_init(self::API_POST_STATUS_WITH_PHOTO);
    curl_setopt($apiCon, CURLOPT_CONNECTTIMEOUT, 30);
    curl_setopt($apiCon, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($apiCon, CURLOPT_POST, true);
    curl_setopt($apiCon, CURLOPT_POSTFIELDS, array('status' => rawurlencode($status), 'photo' => $photoInBinary));
    curl_setopt($apiCon, CURLOPT_HTTPHEADER, array('Host: api.mixi-platform.com', 'Authorization: OAuth ' . $accessToken, 'Content-Type: multipart/form-data'));
    $result = curl_exec($apiCon);        
    curl_close($apiCon);

首先尝试不编码您的状态字段(即,删除
rawurlencode
)。这是一个双重编码,可能这就是为什么你的主人抱怨

(顺便说一句,您不需要显式地设置content-type头;CURL可以做到这一点。)

如果这还不够,您必须重新安排您的请求以使用CURL的magic file upload机制,或者您必须自己构造整个多部分/表单数据字符串

这就是CURL的魔法文件机制的工作原理(从文档到:

要在HTTP“post”中发布的完整数据操作。若要发布文件,请在文件名前面加上@,并使用完整路径。可以通过在文件名后面加上格式为“;type=mimetype”的文件名来显式指定文件类型。此参数可以作为URL编码的字符串(如“para1=val1¶2=val2&…”传递,也可以作为以字段名为键、字段数据为值的数组传递。如果值是数组,则内容类型头将设置为多部分/表单数据。从PHP 5.2.0开始,如果文件以@前缀传递到此选项,则值必须是数组

使用CURL传递多部分/表单数据帖子中特定字段的内容类型的唯一方法是对字段值使用以下语法:
@filepath;type=mime/type

如果您的
$photoInBinary
在文件中开始使用,只需将上述格式的文件名传递给CURL,而不是打开文件并读取数据。

但是,如果您自己在内存中创建了照片,则需要将其写入一个临时文件。以下是您可以执行的操作:

function curlFileUploadData($data, $type='') {
    // $data can be a string or a stream
    $filename = tempnam(sys_get_temp_dir(), 'curlupload-');
    file_put_contents($filename, $data);
    $curlparam = "@{$filename}";
    if ($type) {
        $curlparam .= ";type={$type}";
    }
    return array($curlparam, $filename);
}

list($curlparam, $tmpfile) = curlFileUploadData('thedata', 'image/bmp');

// You can see the raw bits CURL sends if you run 'nc -l 9999' at a command line first
$c = curl_init('http://localhost:9999');
curl_setopt($c, CURLOPT_POSTFIELDS, array('status' => 'good', 'photo' => $curlparam));
curl_exec($c);
curl_close($c);

unlink($tmpfile); // REMEMBER TO DO THIS!!!!
请注意,CURL将在多部分文件上载上设置filename参数。请确保主机不会在任何重要的事情上使用此参数。据我所知,没有办法覆盖CURL发送的filename参数——它始终是给定的


如果您不愿意创建临时文件,并且必须使用CURL,则必须在内存中将整个多部分/表单数据体创建为字符串,并将其作为字符串提供给CURL to
CURL\u POSTFIELDS
,然后手动将内容类型头设置为
多部分/表单数据
。这留给读者作为练习。B这一次你应该考虑使用“替代”,或者“<代码> fOpen< <代码> >用<代码> SturnOrthExtCeCudie()/代码>来设置HTTP方法和标头。

首先尝试不编码你的状态字段(即,删除<代码> RururLeNeks<代码>)。这是双重编码,这可能就是你的主机在抱怨的原因。

(顺便说一句,您不需要显式地设置content-type头;CURL可以做到这一点。)

如果这还不够,您必须重新安排您的请求以使用CURL的magic file upload机制,或者您必须自己构造整个多部分/表单数据字符串

这就是CURL的魔法文件机制的工作原理(从文档到:

要在HTTP“post”中发布的完整数据操作。若要发布文件,请在文件名前面加上@,并使用完整路径。可以通过在文件名后面加上格式为“;type=mimetype”的文件名来显式指定文件类型。此参数可以作为URL编码的字符串(如“para1=val1¶2=val2&…”传递,也可以作为以字段名为键、字段数据为值的数组传递。如果值是数组,则内容类型头将设置为多部分/表单数据。从PHP 5.2.0开始,如果文件以@前缀传递到此选项,则值必须是数组

使用CURL传递多部分/表单数据帖子中特定字段的内容类型的唯一方法是对字段值使用以下语法:
@filepath;type=mime/type

如果您的
$photoInBinary
在文件中开始使用,只需将上述格式的文件名传递给CURL,而不是打开文件并读取数据。

但是,如果您自己在内存中创建了照片,则需要将其写入一个临时文件。以下是您可以执行的操作:

function curlFileUploadData($data, $type='') {
    // $data can be a string or a stream
    $filename = tempnam(sys_get_temp_dir(), 'curlupload-');
    file_put_contents($filename, $data);
    $curlparam = "@{$filename}";
    if ($type) {
        $curlparam .= ";type={$type}";
    }
    return array($curlparam, $filename);
}

list($curlparam, $tmpfile) = curlFileUploadData('thedata', 'image/bmp');

// You can see the raw bits CURL sends if you run 'nc -l 9999' at a command line first
$c = curl_init('http://localhost:9999');
curl_setopt($c, CURLOPT_POSTFIELDS, array('status' => 'good', 'photo' => $curlparam));
curl_exec($c);
curl_close($c);

unlink($tmpfile); // REMEMBER TO DO THIS!!!!
请注意,CURL将在多部分文件上载上设置filename参数。请确保主机不会在任何重要的事情上使用此参数。据我所知,没有办法覆盖CURL发送的filename参数——它始终是给定的


如果您不愿意创建临时文件,并且必须使用CURL,则必须在内存中将整个多部分/表单数据体创建为字符串,并将其作为字符串提供给CURL to
CURL\u POSTFIELDS
,然后手动将内容类型头设置为
多部分/表单数据
。这留给读者作为练习。B这一次你应该考虑使用“替代”,或者甚至<代码> fOpen< <代码> > < >设置http方法和标题。

提问时,最好只描述你的目标,使用简单的语言,而不使用你不理解的术语。@Col.Shrapnel,我理解他。他指的是文件“part”的
内容类型
标题他正确地使用了这些术语。@FrancisAvila每个人都能理解他,但几个删除的答案表明这个问题问得不正确。他问过“如何使用curl上传文件”吗“他马上就得到了正确的答案。”“不,我不是说如何发布内容类型为“im”的图片