16

我正在开发一个跨平台系统,我需要制作一个休息 API 来将它们联系在一起。我在 PHP 方面有很长的经验,我想将它用于这项服务。

我可以 100% 手动开发 API,但我希望有一些很棒的库可以简化我的开发。

有没有人有这样的图书馆经验?你有什么可以推荐的吗?

4

2 回答 2

17

我得到了Popular question这个问题的徽章,所以我觉得是时候详细说明我是如何完成我的 REST 解决方案的了。

对于这个 REST Api,我确实查看了 Laravel、Sympfony2 和 Codeigniter。他们都有一些我喜欢的元素和一些我不喜欢的元素。我主要关心的是如何进行身份验证,因为我有一个相当复杂的算法,我的用户可以使用谷歌或 Facebook 提供的应用程序的 access_token 或 access_tokens 登录。我也更喜欢完全控制我的框架,并且上面提到的框架有一些我觉得不必要且难以解决的元素。因此,我决定制作自己的 REST 解决方案。这并不像人们想象的那么难,它可以通过多种方式完成。我这样做的方式需要一些关于 OOP 编程的知识。

好的,所以开始创建一个名为 REST 的基类。这个类负责处理每个呼叫的所有共同点。像身份验证,解析请求的方法路径,检查access_token等。

此类中的核心内容之一是请求的路径以及如何将其转换为方法。我在 Laravel 的启发下做了这个。我有一个带有key=>的数组,value其中键是它应该匹配的 url,值是要调用的实际方法。我还包括了 Lavavel 在 URL 中解析变量的方式,如下所示:

'/user/(:id)' => 'user_id',

这将匹配任何 /user/[number]。它还会检查这是什么类型的请求,所以如果这是一个简单的 get 方法,它会尝试调用get_user_id. 在调用该方法时,任何被解析的东西(:id)都将用作参数(因此它实际上是在调用get_user_id($id))。

身份验证后,实际的方法调用被评估。我不想要get_user_idREST 类本身中的所有方法(如 ),所以我将它们分解为扩展 REST 类的不同控制器。这是通过查看请求的 url 来完成的。如果是/user/(:id),脚本将检查是否有一个名为userController.php. 如果存在,检查我们要调用的方法是否存在。如果是,请检查参数的数量是否与我们所拥有的相匹配。如果一切正常,则执行该方法,否则返回错误消息。在制作这样的 API 时,结构和错误消息非常重要。

在不同的控制器中,我调用 REST 类的构造函数来获取身份验证、解析 url 等问题。这里棘手的部分是我不想这样做:

$controller = new MyController();
$controller->printResponse();

在每个控制器的底部。所以我做了一个小技巧和一个名为的脚本run.php,它为每个控制器类动态地执行此操作。在我包含之前,我run.php通过简单地保存控制器的路径$path = explode('/',__FILE__);。这在运行脚本中使用。运行脚本如下所示:

// Splitting the file-name, removing the extension
$name = explode('.',$path[count($path)-1]);

// Uppercasing the first letter to be nice and OOP-ish
$classToCall = ucfirst($name[0]);

// Creating a new instance
$controller = new $classToCall();

// Logging
$controller->doLog();

// Printing the final response
$controller->printResponse();

我发现这是我想要构建 API 的完美解决方案。我可以通过在将 url 解析为方法的数组中提供新方法来轻松添加新方法,并且我可以在拆分良好的控制器中添加新方法以实现最大的清洁度。

有些人可能会认为这工作量太大,但实际上我只花了几个小时就可以启动并运行它。我也称这是高度动态的,因为我可以添加新的控制器,如果它们是有效的 url 模式,系统就会识别它们。


一些友好的建议。

如果您决定采用类似于此解决方案的方法,这些可能是一些不错的提示。在每个控制器中,执行以下操作:

public function __construct() {
    // Loading the class-name, setting it in the REST-class, so we can check if it holds the method being called
    $this->className = get_class($this);

    // Calling RESTs constructor
    parent::__construct();
}

我们将需要存储我们当前正在使用的类。这将是UserController或类似的东西。

在 REST 类中,我可以使用这个变量来检查被调用的实际方法是否存在于这个控制器中。我是这样做的:

// Checking if the method exists
if (method_exists($this->className,$method_name)) {
    // Check to see if we have the required number of arguments represented
    $ReflectionClass = new ReflectionClass($this->className);

    if ($ReflectionClass->getMethod($method_name)->getNumberOfParameters() == count($this->methodUrl['args'])) {
        $this->response['response'] = call_user_func_array(array($this, $method_name), $this->methodUrl['args']);

我希望这能让你们都前进。

快乐的编码

于 2013-05-16T22:02:36.720 回答
2

三个月前我也有同样的问题。我花了很多时间研究要使用的最佳 PHP 框架。最后我选择了Laravel

开箱即用,它带有 RESTful 路由和控制器,以及易于使用的身份验证。我在大约一天内启动并运行了一个简单的 REST API

http://laravel.com/docs/routing#the-basics

http://laravel.com/docs/controllers#restful-controllers

它还带有一个很棒的 ORM,这使得设置资源变得超级容易

http://laravel.com/docs/database/eloquent

我正在使用 3.2 版,它的工作原理很吸引人并且很稳定。版本 4 仍处于测试阶段,但确实具有更多面向 REST 的功能(我认为其中之一是它可以更轻松地从控制器中创建资源)

很棒的教程在这里http://net.tutsplus.com/tutorials/php/laravel-4-a-start-at-a-restful-api/

于 2013-03-14T10:41:31.470 回答