7

我开发了一个非常快速和简单的 PHP 应用程序,用于从 XML 文件中读取分类广告并允许用户对其执行 CRUD 操作(这是一项家庭作业)。

我现在的任务是将此应用程序开发为 RESTful 服务。教授实际上似乎对 RESTful 服务没有任何经验,因为他说我的应用程序被发现可以提交下一个作业,而我的研究表明它并没有真正满足所有 RESTful 要求。

无论如何,为了学习目的,我想正确地做到这一点,即使我可以交出我的旧作业并取得好成绩。我在学习从哪里开始时遇到了麻烦;我不确定 RESTful 服务到底是什么。

我认为获得建议的最佳方式是发布我之前分配的示例代码,以了解我如何处理事情以及我需要如何处理事情。

例如,这是我创建新分类广告的方式。

创建.php

//Basically just a list of <INPUT TYPE = "text" NAME = "something"> in the <body> fields

创建成功.php

<html><head><?php $simplerXML = simplexml_load_file('file.xml'); 
//Generate the basic ad information
$newAd = $simplerXML->addChild('advertisement','');
$newAd->addAttribute('category', $_POST["category"]);
$title = $newAd->addChild('title', $_POST["title"]);
$title->addAttribute('ID', $_POST["ID"]);
$pageTitle = $newAd->addChild('pagetitle', $_POST["pagetitle"]);
//etc, for all the SUBMIT boxes

//save the XML
$simplerXML->asXML('file.xml');
echo "<script type='text/javascript'>
//redirect back to ad listing page
window.onload = function () { top.location.href = 'ads.php'; };
</script>";
?></head>
<body></body></html>

我还在为 RUD 操作使用 URL 参数。我听说 URL 参数也是不允许的?

谢谢。

编辑:所以 SWITCH 语句,它是否在 index.php 文件中?然后每个case都会调用一个函数,即POST方法的CreateXML?那么它需要的参数会是对象类型、对象id、内容类型呢?如何获取更新 XML 的值,我是否只是将其发送到包含输入框列表的 Create.php 文件?

4

2 回答 2

15

如果您的服务支持所有 CRUD 操作,则始终建议实现 RESTful 接口。这样做并不难。我已经概述了下面的一些基础知识。

一个 RESTful 服务只做一些事情:

  1. 它使用 HTTP 请求方法进行 CRUD 操作的通信
  2. 它使用 HTTP 状态码来传达响应状态,并且
  3. 它使用 URI 来定义您的资源(文件、您正在访问的数据库项目等)。
  4. 它是无国籍的

这个想法是为了最大限度地减少 HTTP 规范中已经定义的这些东西的自定义通信的开发。


1 - 请求方法

支持 RESTful 服务所需的 4 种 HTTP 请求方法是:

  1. 邮政
  2. 得到
  3. 删除

你可以选择支持

  1. 修补

您可以将这些直接映射到您的 CRUD 操作,如下所示:

  • POST = 创建
  • GET = 检索
  • PUT = 更新
  • 删除 = 删除
  • PATCH = 编辑(部分更新,例如“更改密码”。PUT 变为“替换”)
  • HEAD = 仅标头(有关资源的元数据)

为此,请使用简单的请求方法路由器正确路由请求,如下所示:

switch ($_SERVER["REQUEST_METHOD"]) {
    case "POST":
        // Create action
        break;
    case "GET":
        // Retrieve action
        break;
    case "PUT":
        // Update action
        break;
    case "DELETE":
        // Delete action
        break;
}

2 - 状态码 您应该进一步从您的服务实现 HTTP 状态码以将状态传达回客户端,例如:

  • 20x = 成功
  • 30x = 重定向
  • 40x = 沟通问题
  • 50x = 服务器错误

为此,只需在您的响应前面加上正确的 HTTP 标头输出,例如:

header("Status: 500 Internal Server Error");

您可以在此处参考已实现的 HTTP 状态代码的完整列表:http: //www.w3.org/Protocols/rfc2616/rfc2616-sec10.html


3 - URI 对于 URI,RESTful 服务通常遵循自上而下的分类命名方法,例如

/object_type/id.content_type

例子:

POST /user
PUT /user/1
GET /user/1.json
GET /user/1.html

mod_rewrite您可以在文件中使用 Apache 为上述约定实现一个非常基本的 RESTful 路由器.htaccess,如下所示:

RewriteEngine On
RewriteRule ^([^\/]+)\/([^\.]+)\.(\w+)$  index.php?object_type=$1&object_id=$2&content_type=$3

然后,您将index.php查找适当的 object_type 和 id 以进行适当的路由,例如:

$object = $_GET["object_type"];
$id = (int) $_GET["object_id"];
$content_type = $_GET["content_type"];

// Route from here to a class with the name of the object (e.g. UserController) via __autoload
// or to a file (e.g. user.php) via include, and pass id and content_type as params

4 - STATELESSNESS 简单地说,服务器不为客户端维护任何“状态”。无需存储会话或状态。每个请求代表一个完整的事务。即,如果我 GET user/1,服务器将不记得我这样做了,并且未来的请求将不会依赖于或受以前的请求影响。

如果你实现了这些标准,恭喜,你已经构建了一个 RESTful 服务!

于 2012-12-01T19:06:16.043 回答
4

“RESTful”是一个广义的概念,存在“RESTful”的程度。 维基百科是一个很好的指南

以下是其他答案中未涉及的一些更高级别的特征(这也很好):

  1. 资源在 URL 上可用,最好每个资源只有一个规范的 url。
    • 您可以使用标头指示资源在其他 url 或表示中可用Content-Location
    • 您可以通过与和标头使用内容协商来提供资源的不同表示形式(html、json、xml 等)。Acceptcontent-type
  2. 资源状态的变化完全由单个 HTTP 请求表示。服务器不需要维护状态来服务客户端请求。因此,请求可以很容易地被代理和缓存。
    • 一个常见违反此原则的示例是像“http://example.org/profile”这样的 url,它根据谁登录提供不同的用户配置文件。
    • 最好将资源与授权分开:“http://example.org/profile/{USERID}”将始终为特定用户的用户 ID 提供服务,但如果客户端没有权限,则返回 401(未授权)。(此外,每个请求都应该发送授权信息,这样服务器就不需要会话令牌或类似的服务器端状态。因此,大多数具有基于 cookie 的登录系统的网站都不是纯粹的宁静。)
    • GET 检索资源。这不应该改变资源的状态并且应该可以安全地重复。此属性通常称为“幂等性”。
    • PUT 更新资源。使用诸如条件更新请求(带有if-*标头的 PUT 或 DELETE)之类的技术,您甚至可以实现乐观并发控制。
    • DELETE 删除资源。
    • POST 作为一个包罗万象的“做某事”资源。当您必须做一些不完全适合 http 方法的事情或当您需要执行具有副作用的操作时(例如,在不知道其名称的情况下创建新资源或实现 RPC 协议)时,使用 POST。但是,您应该使用 http 标头和响应代码来显示存在哪些资源副作用,例如带有LocationContent-Location标头的“201 Created”以及受更改影响的 url 列表。
  3. 资源表示是自描述的“超文本”,带有指向其他资源的链接。
    • 违反此原则的示例:假设“http://example.com/articles”是文章列表,其 json 表示形式如下所示[1,2,3,4,5,6]。这是一个文章 ID 列表,但它不是自描述或超文本的——客户端需要知道这是一个文章 ID 列表,并且它需要知道要获取文章资源,它必须构造一个类似“ http://example.org/articles/1”。
    • 最好是这样的回应{"articles":[{"id":1,"url":"http://example.org/articles/1"},...]}。与 html 一样,使用 rest 服务的客户端应该只需要跟随链接(而不是创建链接)来获取其他相关资源。您甚至可以记录可用于操作资源的可用方法——创建、更新、删除等。
于 2012-12-01T20:15:42.663 回答