将多个PHP脚本作为后端REST服务进行处理的最佳方法


Best approach for handling multiple PHP scripts as a backend REST service?

我有一个典型的网站设置,我使用AJAX与PHP脚本通信,然后这些脚本将数据读取和写入MySQL数据库。在我以前的项目中,我需要编写的PHP脚本数量很少,因为我需要读取或写入的数据没有太多变化。这个网站有点不同,我为每个AJAX调用创建不同PHP脚本的正常方法已经产生了大量的PHP脚本。

我决定采用不同的方法,在同一个PHP脚本中对类似的查询进行分组。例如,如果我有以下呼叫:

getGroupById
getAllGroups
创建新组

在我以前的方法中,我会有三个独立的php文件,但现在我有一个可以同时完成这三个文件。

随着项目的发展,我采取的第二种方法被证明是不可维护的。例如,如果我想在同一个脚本中有多个GET调用,我现在必须从AJAX调用向脚本传递另一个参数,以便PHP脚本知道要执行哪个查询。

这两种方法中哪一种会更好?是否有任何众所周知的实践或设计模式来处理此问题?

如果你真的想RESTful,试着让你的PHP文件结构独立于你希望AJAX请求的方式。

一种常见的设计模式是为您拥有的每个单独的数据实体创建一个表示,然后在该表示上定义CRUD操作。然后,HTTP方法头充当应该执行的操作的标识符。

例如,假设您有以下"部分"数据:

  • 用户:您网站的成员
  • :一组成员

如果可能的话,在.htaccess中使用类似Apache的mod_rewrite之类的东西来创建一些好看的URL,如下所示:

  • http://example.com/api/user
  • http://example.com/api/group

接下来,使用AJAX将GETPUTDELETEPOST请求中的参数传递到其中一个URL。通常AJAX库允许您定义GETPOST以外的操作。例如,要在jQuery中删除ID为415、名为Bob的用户,您可以编写以下内容:

$.ajax ({
  url: 'http://example.com/api/user'
  method: 'DELETE',
  data: { id: 415 }
  success: {
    // it works!
  }
});

接下来就是用PHP捕获数据。我建议为每个"数据块"创建一个单独的文件,但当脚本越来越大时,可以更改此文件。这只是调整HTTP服务器的重写规则的问题。

api/user.php

// determine what operation was requested
switch ($_SERVER['REQUEST_METHOD'])
{
  case 'POST':
    $data = $_POST;
    // ...
  case 'GET':
    $data = $_GET;
    // e.g. if an ID was provided, fetch one user, else fetch all of the users
    if (isset ($data ['id']))
      fetch_user ($id);
    else
      fetch_users ();
    break;
  case 'PUT':
    $data = parse_str (file_get_contents('php://input'), $put_vars); // see below
    // ...
  case 'DELETE':
    $data = parse_str (file_get_contents('php://input'), $put_vars); // see below
    // ...
  default:
   // 405 = Method Not Allowed
   http_response_code(405); // for PHP >= 5.4.0
   exit;
}
// a whole list of functions to add, retrieve, delete and manipulate users
function fetch_user ($id)
{
  $query = "SELECT * FROM users WHERE id = ...";
  // ...
}
function fetch_users ()
{
  // ...
}

来源:

  • 哪些HTTP方法与哪些CRUD方法匹配
  • PHP中REST库的一个示例
  • 如何用PHP发送状态代码
  • PHP的PUT方法支持
  • 关于REST方法的一些说明