简体   繁体   English

PHP curl 文件传输

[英]PHP curl file transfer

we're using GLPI API we need to create a ticket linked with documents .我们正在使用 GLPI API 我们需要创建一个与文档链接的票证。

The only curl part that i can't translate it's the document's upload .我无法翻译的唯一卷曲部分是文档的上传。

With Curl (working) :随着卷曲(工作):

curl -i -X POST "http://glpitest/glpi/apirest.php/Document" -H "Content-Type: multipart/form-data" -H "Session-Token:sessiontoken"-H "App-Token:apptoken" -F "uploadManifest={\"input\": {\"name\": \"Uploaded document\", \"_filename\" : \"test.txt\"}};type=application/json" -F "filename[0]=@test.txt" "http://glpitest/glpi/apirest.php/Document"

But i can't translate this is in PHP CURL i tried something like this :但我无法翻译这是在 PHP CURL 我试过这样的事情:

  $headers = array(
 'Authorization: Basic ' . $_SESSION['encodelogin'],
 'App-Token:' . $_SESSION['app_token'], // <---
 'Session-Token:' . $_SESSION['session_token'],
 'Http_Accept: application/json',

);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_exec($ch);
echo $url = $_SESSION['api_url'] . "/Document";

$cfile = new CURLFile('testpj.txt', 'text/plain', 'test_name');
//$manifest = 'uploadManifest={"input": {"name": "test", "_filename" : "testpj.txt"}};type=application/json filename[0]=@'+$cfile;
$post = ["{\"input\": {\"name\": \"test\", \"_filename\" : \"testpj.txt\"}};type=application/json}", @"C:\\xampp\htdocs\glpi"];
print_r($post);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);

the example in the api: api中的例子:

$ curl -X POST \
-H 'Content-Type: multipart/form-data' \
-H "Session-Token: 83af7e620c83a50a18d3eac2f6ed05a3ca0bea62" \
-H "App-Token: f7g3csp8mgatg5ebc5elnazakw20i9fyev1qopya7" \
-F 'uploadManifest={"input": {"name": "Uploaded document", "_filename" : ["file.txt"]}};type=application/json' \
-F 'filename[0]=@file.txt' \
'http://path/to/glpi/apirest.php/Document/'

< 201 OK
< Location: http://path/to/glpi/api/Document/1
< {"id": 1, "message": "Document move succeeded.", "upload_result": {...}}

update : I tried @hanshenrik but i have an error .更新:我试过@hanshenrik,但我有一个错误。

["ERROR_JSON_PAYLOAD_INVALID","JSON payload seems not valid"] ["ERROR_JSON_PAYLOAD_INVALID","JSON 负载似乎无效"]

in the api.class.php :在 api.class.php 中:

if (strpos($content_type, "application/json") !== false) {
     if ($body_params = json_decode($body)) {
        foreach ($body_params as $param_name => $param_value) {
           $parameters[$param_name] = $param_value;
        }
     } else if (strlen($body) > 0) {
        $this->returnError("JSON payload seems not valid", 400, "ERROR_JSON_PAYLOAD_INVALID",
                           false);
     }
     $this->format = "json";

  } else if (strpos($content_type, "multipart/form-data") !== false) {
     if (count($_FILES) <= 0) {


        // likely uploaded files is too big so $_REQUEST will be empty also.
        // see http://us.php.net/manual/en/ini.core.php#ini.post-max-size
        $this->returnError("The file seems too big!".print_r($_FILES), 400,
                           "ERROR_UPLOAD_FILE_TOO_BIG_POST_MAX_SIZE", false);
     }

     // with this content_type, php://input is empty... (see http://php.net/manual/en/wrappers.php.php)
     if (!$uploadManifest = json_decode(stripcslashes($_REQUEST['uploadManifest']))) {

     //print_r($_FILES);
        $this->returnError("JSON payload seems not valid", 400, "ERROR_JSON_PAYLOAD_INVALID",
                           false);
     }

I have no uploadManifest in $_REQUEST and if i put the the filename[0]file i have the curl error 26 (can't read file) .我在 $_REQUEST 中没有 uploadManifest,如果我把 filename[0] 文件我有 curl 错误 26 (can't read file) 。

Thank you谢谢

translating翻译

-F "uploadManifest={\"input\": {\"name\": \"Uploaded document\", \"_filename\" : \"test.txt\"}};type=application/json"

is tricky because php doesn't really have native support for adding Content-Type headers (or any headers really) to members of a multipart request, with the only *exception* (known to me) being CURLFile's "Content-Type" and Content-Disposition's "filename" header... with that in mind, you can work around this by putting your data in a file and creating a CURLFile() around that dummy file, but it's.. tricky and stupid-looking (because PHP's curl api wrappers lacks proper support for it)很棘手,因为 php 并没有真正支持向多部分请求的成员添加 Content-Type 标头(或任何标头),唯一的 *exception*(我知道)是 CURLFile 的“Content-Type”和 Content -Disposition 的“文件名”标头...考虑到这一点,您可以通过将数据放入文件并在该虚拟文件周围创建 CURLFile() 来解决此问题,但它......看起来很棘手和愚蠢(因为 PHP 的 curl api 包装器缺乏对它的适当支持)

with the CURLFile workaround, it would look something like:使用 CURLFile 解决方法,它看起来像:

<?php
declare(strict_types = 1);
$ch = curl_init();
$stupid_workaround_file1h = tmpfile();
$stupid_workaround_file1f = stream_get_meta_data($stupid_workaround_file1h)['uri'];
fwrite($stupid_workaround_file1h, json_encode(array(
    'input' => array(
        'name' => 'Uploaded document',
        '_filename' => 'test.txt'
    )
)));
curl_setopt_array($ch, array(
    CURLOPT_URL => "http://glpitest/glpi/apirest.php/Document",
    CURLOPT_POST => 1,
    CURLOPT_HEADER => 1,
    CURLOPT_HTTPHEADER => array(
        "Session-Token:sessiontoken",
        "App-Token:apptoken"
    ),
    CURLOPT_POSTFIELDS => array(
        'uploadManifest' => new CURLFile($stupid_workaround_file1f, 'application/json', ' '), // https://bugs.php.net/bug.php?id=79004
        'filename[0]' => new CURLFile('test.txt', 'text/plain')
    )
));
curl_exec($ch);
curl_close($ch);
fclose($stupid_workaround_file1h);

Thanks for the Help .谢谢您的帮助 。

$document can be a $_FILES['whatever'] post . $document 可以是 $_FILES['whatever'] 帖子。

Works on GLPI api .适用于 GLPI api 。

<?php
declare (strict_types = 1);
session_start();
$document = array('name' => 'document', 'path' => 'C:\xampp\htdocs\glpi\document.pdf', 'type' => 'txt', 'name_ext' => 'document.pdf');
$url = $_SESSION['api_url'] . "/Document";
$uploadManifest = json_encode(array(
 'input' => array(
  'name' => $document['name'],
  '_filename' => $document['name_ext'],
 ),
));

$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLINFO_HEADER_OUT, 1);

curl_setopt_array($ch, array(
 CURLOPT_URL => $url,
 CURLOPT_POST => 1,
 CURLOPT_HEADER => 1,
 CURLOPT_HTTPHEADER => array(
  'Content-Type: multipart/form-data',
  'Authorization: Basic ' . $_SESSION['encodelogin'],
  'App-Token:' . $_SESSION['app_token'], // <---
  'Session-Token:' . $_SESSION['session_token'],
 ),

 CURLOPT_POSTFIELDS => array(
  'uploadManifest' => $uploadManifest,
  'filename[0]' => new CURLFile($document['path'], $document['type'], $document['name_ext']),
 ),
));
print_r($_REQUEST);
echo $result = curl_exec($ch);

echo "erreur n° " . curl_errno($ch);
$header_info = curl_getinfo($ch, CURLINFO_HEADER_OUT) . "/";
print_r($header_info);
if ($result === false) {
 $result = curl_error($ch);
 echo stripslashes($result);

}
curl_close($ch);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM