2012-03-13 168 views
12

我目前正在PHP中开发一个Restful Json-API。我想发送一个PUT请求到items/:id来更新记录。数据将作为application/json转移。PHP获取PUT请求正文

我要调用的API与

curl -H "Content-Type: application/json" -X PUT -d '{"example" : "data"}' "http://localhost/items/someid" 

在服务器端,我不能检索请求主体。我试过

file_get_contents("php://input"); 

但是这会返回一个空字符串。另外fopen()/fread()组合不起作用。

当通过POST调用时,一切都很好,我可以在服务器端完美地阅读json。但该API不再是Restful了。有没有人有这个解决方案?是否有另一种发送和接收Json的方式?

顺便说一句,我正在开发的API与Slim Framework

+0

你试过fopen(“php:// input”,“r”)吗? – sethcall 2012-03-13 13:00:18

+0

是的,没有工作。 – aladin 2012-03-13 13:02:38

+1

真棒,你使用苗条。我希望你有很好的经历。我真的很喜欢我的SLIM restful API创建 – Jake 2012-03-13 13:05:44

回答

13

php://input只可读一次PUT请求:

注:流用PHP打开://输入只能读一次;该流不支持查找操作。但是,根据SAPI实现,可能会打开另一个php://输入流并重新开始读取。这仅在请求主体数据已被保存时才可能。通常情况下,这是POST请求的情况,而不是其他请求方法,例如PUT或PROPFIND。

http://php.net/manual/en/wrappers.php.php

根据要求的超薄框架已经读取的数据。从请求对象中读取已读取的数据。

+4

非常感谢,这解决了我的问题。我可以通过$ app-> request-> getBody()获取原始数据。然后做一个json_decode。我不知道这种方法,因为它不在文档中。 – aladin 2012-03-13 13:30:06

+0

+1这是我使用restTonic PHP框架的问题。 $ this-> request-> data变量已经存放了PUT主体。我已经在我的POST处理程序中读取了php://输入,并且无法明白为什么PUT处理程序不能使用相同的方法来处理其正文。 – Neek 2013-11-22 12:14:25

-1

我前几天读的是SLIM框架文档,它说有些浏览器在PUT和DELETE方面有问题。

摘录:

不幸的是,现代的浏览器没有为PUT请求提供原生支持。要解决此限制,确保你的HTML窗体的方法是“后”,那么方法重写参数添加到您的HTML表单是这样的:

<form action="/books/1" method="post"> 
    ... other form fields here... 
    <input type="hidden" name="_METHOD" value="PUT"/> 
    <input type="submit" value="Update Book"/> 
</form> 

来源:http://www.slimframework.com/documentation/stable

+0

OP使用Curl执行HTTP PUT操作。 – GordonM 2012-03-13 13:05:52

+0

我对此也有点新意,但cURL只是放弃了浏览器问题?如果他通过PHP来执行curl请求,那该怎么办? (我不是说他是,我是说命令行cURL的好处仍然存在) – Jake 2012-03-13 13:11:26

+0

@Jake:是的,使用cURL放弃了浏览器问题。没有浏览器涉及他致电该服务的方式。 – Crontab 2012-03-13 13:21:55

0

PHP manual的例子使用的fopen以读模式访问php://输入。你试过这样做吗?

编辑:manual page for PHP://说一些似乎表明PUT数据可能无法在某些情况下可用的东西!

注意:使用php://输入打开的流只能读取一次; 流不支持查找操作。但是,根据SAPI实现 ,可能会打开另一个php://输入 流并重新开始读取。这仅在请求主体 数据已被保存时才有可能。通常,POST请求的情况是 ,但不包括其他请求方法,例如PUT或PROPFIND。

我不知道这会在哪里给你PUT处理。一页似乎说这是可能的,另一个似乎暗示它不会在错误的情况下工作

1

在服务器端,我无法检索请求正文。我试过file_get_contents(“php:// input”);

每个请求只能使用file_get_contents('php://input', 'r');一次。检索它的值也会截断值,所以如果你调用它两次,它会返回一个空字符串。斯利姆的请求对象包含您需要的值,因此:

<?php 
$app = new Slim(); 

$app->put('/items/someid', function() use ($app) { 
    echo $app->request()->put('example'); // should display "data". 
}); 
+1

这对于url编码的数据是正确的,但对于原始json不适用。如果我发送编码的数据url,我可以通过Slim的请求对象访问它。不适合json艰难。 – aladin 2012-03-13 13:21:49

+0

问题依然存在;你只能从php://输入*一次*读取,而Slim已经完成了。你将不得不使用Slim的请求对象来获取你的值。 – 2012-03-13 13:24:39

+1

显然Slim框架在施工时读取请求体,所以php://输入已被删除。谢谢! – aladin 2012-03-13 13:32:11