简体   繁体   English

PHP得到PUT请求体

[英]PHP get PUT request body

I'm currently developing a Restful Json-API in PHP. 我目前正在用PHP开发Restful Json-API。 I want to send a PUT-Request to items/:id to update a record. 我想发送一个PUT-Request到items/:id来更新记录。 The data will be transferred as application/json . 数据将作为application/json传输。

I want to call the API with 我想用API调用API

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

On the server side, I'm not able the retrieve the request body. 在服务器端,我无法检索请求正文。 I tried 我试过了

file_get_contents("php://input");

but this returns an empty string. 但这会返回一个空字符串。 Also a fopen() / fread() combination doesn't work. fopen() / fread()组合也不起作用。

When calling via POST, everything works great, I can read the json perfectly on the server side. 通过POST调用时,一切都很好,我可以在服务器端完美地读取json。 But the API isn't Restful anymore. 但API不再是Restful了。 Does anyone have a solution for this? 有人有解决方案吗? Is there another way to send and receive Json? 还有另一种发送和接收Json的方式吗?

btw, I'm developing the API with the Slim Framework . 顺便说一句,我正在使用Slim Framework开发API。

php://input is only readable once for PUT requests: php://input只能读取一次PUT请求:

Note: A stream opened with php://input can only be read once; 注意:使用php://输入打开的流只能读取一次; the stream does not support seek operations. 流不支持搜索操作。 However, depending on the SAPI implementation, it may be possible to open another php://input stream and restart reading. 但是,根据SAPI实现,可能会打开另一个php://输入流并重新开始读取。 This is only possible if the request body data has been saved. 只有在保存了请求正文数据后才能执行此操作。 Typically, this is the case for POST requests, but not other request methods, such as PUT or PROPFIND. 通常,这是POST请求的情况,但不是其他请求方法,例如PUT或PROPFIND。

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

The Slim framework already reads the data upon request. Slim框架已根据请求读取数据。 Take the data from the Request object, into which it has been read. 从Request对象中获取数据,并将其读取到该对象中。

On the server side, I'm not able the retrieve the request body. 在服务器端,我无法检索请求正文。 I tried file_get_contents("php://input"); 我试过file_get_contents(“php:// input”);

You can only use file_get_contents( 'php://input', 'r' ); 你只能使用file_get_contents( 'php://input', 'r' ); once per request. 每次请求一次。 Retrieving its values will truncate the values as well, so if you call it twice, it'll return an empty string. 检索它的值也会截断值,所以如果你调用它两次,它将返回一个空字符串。 Slim's request object contains the values you need, so: Slim的请求对象包含您需要的值,因此:

<?php
$app = new Slim( );

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

The example from the PHP manual uses fopen to access php://input in read mode. PHP手册中的示例使用fopen以读取模式访问php://输入。 Have you tried doing it that way instead? 你尝试过这样做吗?

EDIT: The manual page for PHP:// says some stuff that seems to suggest that PUT data might not be available in some cases! 编辑: PHP手册页://说一些似乎暗示PUT数据可能在某些情况下不可用的东西!

Note: A stream opened with php://input can only be read once; 注意:使用php://输入打开的流只能读取一次; the stream does not support seek operations. 流不支持搜索操作。 However, depending on the SAPI implementation, it may be possible to open another php://input stream and restart reading. 但是,根据SAPI实现,可能会打开另一个php://输入流并重新开始读取。 This is only possible if the request body data has been saved. 只有在保存了请求正文数据后才能执行此操作。 Typically, this is the case for POST requests, but not other request methods, such as PUT or PROPFIND. 通常,这是POST请求的情况,但不是其他请求方法,例如PUT或PROPFIND。

I don't know where this will leave you regarding PUT processing. 我不知道这将留下你关于PUT处理的地方。 One page seems to say it's possible, the other seems to imply that it won't work under the wrong set of circumstances 一页似乎说它是可能的,另一页似乎暗示它不会在错误的环境下工作

I was reading the SLIM framework documentation the other day and it said that some browsers have problems with PUT and DELETE. 我前几天正在阅读SLIM框架文档,它说有些浏览器在PUT和DELETE方面存在问题。

Excerpt: 摘抄:

Unfortunately, modern browsers do not provide native support for PUT requests. 不幸的是,现代浏览器不提供对PUT请求的本机支持。 To work around this limitation, ensure your HTML form's method is “post”, then add a method override parameter to your HTML form like this: 要解决此限制,请确保HTML表单的方法是“post”,然后将方法覆盖参数添加到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>

Source: http://www.slimframework.com/documentation/stable 资料来源: http//www.slimframework.com/documentation/stable

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

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