Como postar JSON para PHP com curl

108

Posso estar errado, mas tenho tentado a tarde toda executar o comando curl post neste tutorial de recesso do framework PHP. O que eu não entendo é como o PHP deve interpretar meu POST, ele sempre aparece como um array vazio.

curl -i -X POST -d '{"screencast":{"subject":"tools"}}'  \
      http://localhost:3570/index.php/trainingServer/screencast.json

(A barra ali é só para não me parecer um idiota, mas executei no windows usando PHP 5.2, também tentei em um servidor Linux, mesma versão do Linux curl)

Deve haver algo que estou faltando porque parece bem direto, o post simplesmente não está sendo interpretado direito, se fosse, tudo daria certo.

Isso é o que eu recebo de volta:

Conflito HTTP / 1.1 409
Data: Sex, 01 de maio de 2009, 22:03:00 GMT
Servidor: Apache / 2.2.8 (Win32) PHP / 5.2.6
X-Powered-By: PHP / 5.2.6
Transfer-Encoding: chunked
Tipo de conteúdo: text / html; charset = iso-8859-1

{"screencast": {"id": null, "subject": null, "body": null,
         "dataUrl": null, "dataMedium": null, "createdOn": null, "autor": null}}
Peter Turner
fonte
Você poderia copiar e colar seu arquivo .php também? Tem certeza de que o URL localhost: 3570 / index.php / trainingServer / screencast.json executa seu script? Não se parece com um URL PHP.
pts
@pts; Peter está usando uma estrutura MVC de algum tipo, dê uma olhada em index.php nessa URL.
Alan Storm
@pts Estou usando Delphi para PHP (daí o: 3570) e o framework Recess MVC sem o arquivo .htaccess, daí o index.php / no url.
Peter Turner
7
Não se esqueça de enviar como application/json.
Gumbo de
1
Não é necessário escapar das aspas duplas ao incorporá-las em simples.

Respostas:

107

A análise de Jordans de por que a matriz $ _POST não está preenchida está correta. No entanto, você pode usar

$data = file_get_contents("php://input");

para apenas recuperar o corpo http e tratá-lo você mesmo. Veja streams de entrada / saída PHP .

De uma perspectiva de protocolo, isso é realmente mais correto, já que você não está realmente processando dados de formulário de várias partes http. Além disso, use application / json como tipo de conteúdo ao postar sua solicitação.

Emil H
fonte
7
Fazer json_decode (file_get_contents ("php: // input"), true) funcionou. Obrigado
Peter Turner
Realmente ajudou minha situação também! Obrigado Emil H!
Steve
FANTÁSTICO. Eu estava tendo muitos problemas com o Zend pensando que ele estava removendo a postagem. Uma extração simples que funcionou para mim. Também a adição de Peter Turners de json_decode () fornecendo um objeto \ stdClass. Eu o usei para respostas de ping API Garmin
JI-Web
120

Normalmente, o parâmetro -dé interpretado como codificado por formulário. Você precisa do -Hparâmetro:

curl -v -H "Content-Type: application/json" -X POST -d '{"screencast":{"subject":"tools"}}' \
http://localhost:3570/index.php/trainingServer/screencast.json
Jim Carrig
fonte
18

Acredito que você esteja obtendo uma matriz vazia porque o PHP espera que os dados postados estejam em um formato Querystring (chave = valor & chave1 = valor1).

Tente alterar sua solicitação curl para:

curl -i -X POST -d 'json={"screencast":{"subject":"tools"}}'  \
      http://localhost:3570/index.php/trainingServer/screencast.json

e veja se isso ajuda em alguma coisa.

Jordan S. Jones
fonte
Sim, o -H "Content-Type: application/json"não funcionou para mim.
PJ Brunet
13

Você precisa definir alguns sinalizadores extras para que curl envie os dados como JSON.

comando

$ curl -H "Content-Type: application/json" \
       -X POST \
       -d '{"JSON": "HERE"}' \
       http://localhost:3000/api/url

bandeiras

  • -H: cabeçalho personalizado, o próximo argumento deve ser cabeçalho
  • -X: verbo HTTP personalizado, o próximo argumento deve ser verbo
  • -d: envia o próximo argumento como dados em uma solicitação HTTP POST

Recursos

Chris Knadler
fonte
1

Você deve escapar das aspas desta forma:

curl -i -X POST -d '{\"screencast\":{\"subject\":\"tools\"}}'  \
  http://localhost:3570/index.php/trainingServer/screencast.json

fonte
No Windows, isso realmente funcionou para mim, mas usar aspas duplas para incluir toda a string json.
Meatvest
no Windows, você deve escapar das aspas duplas, como Josef sugeriu acima. Ele está certo.
Bobo