无法使用 curl_setopt 为 JSON 数据发出 POST 请求

Cannot make a POST request with curl_setopt for a JSON data

我想使 PHP 等效于此 CURL 语句:

curl -X POST -H 'Content-Type: application/json' -u Administrator:Administrator -d '{"entity-type": "document", "name": "myNewDoc", "type": "File", "properties": {"dc:title": "My new doc", "file:content": {"upload-batch": "<myBatchId>", "upload-fileId": "0"}}}' http://192.168.128.101:8080/nuxeo/api/v1/path/Knowledge Base/workspaces/Archives Projets

这是我的代码:

    /**
     * @Rest\Post("/api/getiterop", name="api_get_iterop")
     * @Rest\RequestParam(name="sary", nullable=true)
     */
    public function getIteropForm(Request $req)
    {
        $userNameNuxeo = "api-kb";
        $mdpNuxeo = "zKqWQd3QhmigOLqVliqN#";
        // création et récupération du batch_id dans nuxeo
        $nuxeoBatchId = file_get_contents('http://192.168.128.101:8080/nuxeo/api/v1/upload/', false, stream_context_create([
                                                        'http' => [
                                                                    'method' => 'POST',
                                                                    'header'  => array("Content-type: application/octet-stream", "Authorization: Basic " . base64_encode ($userNameNuxeo.":".$mdpNuxeo)),
                                                                    'content' => http_build_query([]) // de la forme 'key1' => 'Hello world!', 'key2' => 'second value'
                                                                    ]
                                                ])
                                        );
        $nuxeoBatchId = json_decode($nuxeoBatchId, true);
        $nuxeoBatchId = $nuxeoBatchId['batchId'];
        // dossier pour mettre les fichiers uploadés
        $iteropFolderPath = "../iterop_files/" . $nuxeoBatchId . "/";
        $iteropFolder = true;
        if (file_exists($iteropFolderPath) === false) {
            $iteropFolder = mkdir($iteropFolderPath, 0777, true);
        }
        // déplacer les fichiers uploadés
        if (stripos($req->headers->get('Content-Type'), 'multipart') !== false) {
            $fichiers = $req->files;
            if (count($fichiers) > 0) {
                $fileIdx = 0;
                foreach($fichiers as $field_name => $fichier) {
                    if ($fichier != null) {
                        if ($iteropFolder === true) {
                            // déplacement du fichier iterop
                            $iteropFile = $fichier->move($iteropFolderPath, $fichier->getClientOriginalName());

                            // envoi du fichier associé au batch vers nuxeo , par chunks
                            $nbChunks = 5;
                            for($chunkIdx = 0 ; $chunkIdx < $nbChunks ; $chunkIdx++) {
                                $curl = curl_init('http://192.168.128.101:8080/nuxeo/api/v1/upload/' . $nuxeoBatchId . '/' . $fileIdx);
                                curl_setopt($curl, CURLOPT_POST, true);
                                curl_setopt($curl, CURLOPT_POSTFIELDS, array('file' => '@' . realpath($iteropFolderPath . $fichier->getClientOriginalName()) . ';filename=' . $fichier->getClientOriginalName()));
                                curl_setopt($curl, CURLOPT_HTTPHEADER, array("Authorization: Basic " . base64_encode($userNameNuxeo.":".$mdpNuxeo), 'X-Upload-Type: chunked', 'X-Upload-Chunk-Index:'.$chunkIdx, 'X-Upload-Chunk-Count: '.$nbChunks, 'X-File-Name: ' . $fichier->getClientOriginalName(), 'X-File-Type: ' . $iteropFile->getMimeType(), 'Content-Type: application/octet-stream', 'X-File-Size: ' . filesize(realpath($iteropFolderPath . $fichier->getClientOriginalName()))));
                                curl_exec($curl);
                                curl_close($curl);
                            }
                            
                            // here is the bug
                            $name = $fichier->getClientOriginalName();
                            $pos = strrpos($name, '.');
                            $doc = array("entity-type" => "document",
                                        "name" => false === $pos ? $name : substr($name, 0, $pos),
                                        "type" => "File",
                                        "properties" => array("dc:title" => false === $pos ? $name : substr($name, 0, $pos),
                                                              "file:content" => array("upload-batch" => $nuxeoBatchId, "upload-fileId" => $fileIdx)
                                                            )
                                        );
                            $curl = curl_init('http://192.168.128.101:8080/nuxeo/api/v1/path/Knowledge Base/workspaces/Archives Projets');
                            curl_setopt($curl, CURLOPT_POST, true);
                            curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($doc));
                            curl_setopt($curl, CURLOPT_HTTPHEADER, array("Authorization: Basic " . base64_encode($userNameNuxeo.":".$mdpNuxeo), 'Content-Type: application/json'));
                            curl_exec($curl);
                            curl_close($curl);
                        }
                    }
                    $fileIdx++;
                }
            }
        }

        $response = new Response();
        $response->headers->set('Access-Control-Allow-Origin', '*');
        $response->headers->set('Content-Type', 'application/json');
        $response->setContent(json_encode(array("batchId" => $nuxeoBatchId)));
        return $response;
    }

但在运行时出现错误:HTTP Status 505 – HTTP Version Not Supported

所以我的代码有什么问题?

  1. 试试这个 resource:

例如,您的请求已转换为此 php 脚本:

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'http://192.168.128.101:8080/nuxeo/api/v1/path/Knowledge');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"entity-type\": \"document\", \"name\": \"myNewDoc\", \"type\": \"File\", \"properties\": {\"dc:title\": \"My new doc\", \"file:content\": {\"upload-batch\": \"<myBatchId>\", \"upload-fileId\": \"0\"}}}");
curl_setopt($ch, CURLOPT_USERPWD, 'Administrator' . ':' . 'Administrator');

$headers = array();
$headers[] = 'Content-Type: application/json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
  1. 而且我不确定 url 中的 space。你确定 url 是正确的并且应该有 space 吗?根据RFC 1738:

space 字符是不安全的,因为重要的 space 可能会消失,而无关紧要的 space 可能会在 URL 被转录或排版或受到word-processing 程序的处理。

  1. 如果 url 正确,请尝试使用此函数对其进行编码 urlencode

  2. 尝试在您的终端 curl 请求中添加 --head 选项。因此您将获得支持的 HTTP 版本作为响应。并添加新的 curl_setopt($ch, CURLOPT_HTTP_VERSION, /*Correct http version here*/); 具有同等价值。

例如:

curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0 );

这里是 list 可用常量。