PHP REST放置/删除选项

时间:2012-08-23 06:02:19

标签: php rest

尝试了解REST中创建应用的PHP方法。

我在理解如何从php脚本发送put / delete时遇到问题。

在互联网上,我只能找到如何确定已发送的php方法。

if($_SERVER['REQUEST_METHOD'] == 'DELETE')

但是如何发送此DELETE方法?

Normaly当我想从DB删除一些记录时我做了什么我有正常的html表单,方法设置为post / get并记录db id然后我按提交按钮发送post / get表单。

如何创建此提交以发送delete / put方法?

4 个答案:

答案 0 :(得分:7)

使用除GET或POST之外的http方法,有两种常见的方法可以从HTML页面发送请求。

#1 :使用html表单发送POST请求,但包含一个隐藏的表单字段,告诉服务器将请求视为使用不同的方法。这是方法outlined by @xdazz

<form method="post" action="my_resource.php">
  ...
  <input type="hidden" name="REQUEST_METHOD" value="PUT" />
<form>

在您的PHP脚本"my_resource.php"中,您必须查看两者真实请求方法,提交的表单字段,以确定要调用的逻辑:

/* my_resource.php */

$method = strtolower($_SERVER['REQUEST_METHOD']);
if( $method === 'post' && isset($_REQUEST['REQUEST_METHOD'])) {
    $tmp = strtolower((string)$_REQUEST['REQUEST_METHOD']);
    if( in_array( $tmp, array( 'put', 'delete', 'head', 'options' ))) {
        $method = $tmp;
    }
    unset($tmp);
}

// now, just run the logic that's appropriate for the requested method
switch( $method ) {
    case "get":
        // logic for GET here
        break;

    case "put":
        // logic for PUT here
        break;        

    case "post":
        // logic for POST here
        break;

    case "delete":
        // logic for DELETE here
        break;

    case "head":
        // logic for DELETE here
        break;

    case "options":
        // logic for DELETE here
        break;

    default:
        header('HTTP/1.0 501 Not Implemented');
        die();
}

注意:您可以将上述逻辑放入每个页面(或从每个页面调用它)。另一种方法是构建代理脚本(例如"rest-form-proxy.php")。然后,您网站中的所有表单都将提交给代理,包括request_method,目标网址。代理将提取所提供的信息,并使用正确请求的http方法将请求转发到所需的URL。

代理方法是在每个脚本中嵌入逻辑的绝佳替代方法。如果您确实构建了代理,请务必检查所请求的URL,并禁止任何不指向您自己站点的URL。未能执行此检查将允许其他人使用您的代理在其他网站上发起恶意攻击;它还可能危及您网站的安全和/或隐私。

-

#2 :在HTML页面中使用Javascript发起XMLHttpRequest。这是一种更复杂的方法,需要一些javascript,但在某些情况下它可以更灵活。它允许您在不重新加载页面的情况下将请求发送到服务器。它还允许您以多种不同格式发送数据(您不仅限于从html表单发送数据)。例如:

<button onclick="doSave()">Save</button>

<script>
    var myObject = {
       // ... some object properties that 
       // that you'll eventually want to save ...
    };

    function doSave() {
        var xhr = createxmlhttprequest();

        // initialize the request by specifying the method 
        // (ie: "get", "put", "post", "delete", etc.), and the
        // url (in this case, "my_resource.php").  The last param
        // should always be `true`.

        xhr.open("put", "my_resource.php", true);
        xhr.setRequestHeader('Content-Type', 'application/json');

        xhr.onreadystatechange = function() {
           if (xhr.readystate != 4) { return; }
           var serverresponse = xhr.responsetext;

           // ... this code runs when the response comes back
           // from the server.  you'll have to check for success
           // and handle the response document (if any).
        };

        // this initiates the request, sending the contents
        // of `myObject` as a JSON string.  

        xhr.send(JSON.stringify(myObject));

        // The request runs in the background
        // The `onreadystatechange` function above
        // detects and handles the completed response.
    }
</script>

XMLHttpRequest还有很多内容,比我在上面的基本示例中所示。如果您选择此路线,请仔细研究。除此之外,请确保正确处理各种错误情况。跨浏览器兼容性也存在许多问题,其中许多问题可以通过使用中间人来解决,例如jQuery's $.ajax() function

最后,我应该注意到上述两种方法并不相互排斥。只要您构建服务器以便它可以处理任何类型的请求(如上面的#1所示),就可以将表单用于某些请求,并将XMLHttpRequest用于其他请求。

答案 1 :(得分:4)

HTML表单仅支持GET和POST,因此在普通的Web应用程序中,您需要使用隐藏字段来指定请求方法,这是大多数框架所做的。

<form method="post" action="...">
  ...
  <input type="hidden" name="REQUEST_METHOD" value="PUT" />
<form>

答案 2 :(得分:3)

如果您使用的是Chrome,则可以使用Postman来测试您的REST服务。它允许发送任何类型的命令 - DELETE,PUT,还有OPTIONS,PATCH等。

在Firefox上,您可以使用RESTClient等。

答案 3 :(得分:3)

通常的方法是使用cURL

$ch = curl_init('YOUR_URL');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE'); // curl_setopt($ch, CURLOPT_PUT, true); - for PUT
curl_setopt($ch, CURLOPT_POSTFIELDS, 'some_data');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);  // DO NOT RETURN HTTP HEADERS
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);  // RETURN THE CONTENTS OF THE CALL
$result = curl_exec($ch);