GITHUB:https://github.com/jacwright/RestServer

简介:

一个PHP REST服务器,用于提供非常轻量级的REST API。很容易上手。独立于其他库和框架。支持HTTP身份验证。

参考Zend Framework,该框架省略了Zend Framework MVC附带的大量类。还有一些有用的功能要添加(例如XML支持)。

RestServer到目前为止,该框架的解决方案是一个JSON REST服务器。添加对XML或其他格式的支持应该是微不足道的,但是必须假设您的对象在XML中的样子(XML-RPC样式,您自己的自定义XML格式等)。

首先,我们将查看您编写的用于处理请求的类,然后我们将查看如何在index.php文件中将它们绑定在一起。

使用教程:

从URL到类方法获取请求的映射都在类的doc-comments中。以下是处理某些用户操作的类的示例:

<?php

use \Jacwright\RestServer\RestException;

class TestController
{
/**
* Returns a JSON string object to the browser when hitting the root of the domain
*
* @url GET /
*/
public function test()
{
return "Hello World";
} /**
* Logs in a user with the given username and password POSTed. Though true
* REST doesn't believe in sessions, it is often desirable for an AJAX server.
*
* @url POST /login
*/
public function login()
{
$username = $_POST['username'];
$password = $_POST['password']; //@todo remove since it is not needed anywhere
return array("success" => "Logged in " . $username);
} /**
* Gets the user by id or current user
*
* @url GET /users/$id
* @url GET /users/current
*/
public function getUser($id = null)
{
// if ($id) {
// $user = User::load($id); // possible user loading method
// } else {
// $user = $_SESSION['user'];
// } return array("id" => $id, "name" => null); // serializes object into JSON
} /**
* Saves a user to the database
*
* @url POST /users
* @url PUT /users/$id
*/
public function saveUser($id = null, $data)
{
// ... validate $data properties such as $data->username, $data->firstName, etc.
// $data->id = $id;
// $user = User::saveUser($data); // saving the user to the database
$user = array("id" => $id, "name" => null);
return $user; // returning the updated or newly created user object
} /**
* Gets user list
*
* @url GET /users
*/
public function listUsers($query)
{
$users = array('Andra Combes', 'Valerie Shirkey', 'Manda Douse', 'Nobuko Fisch', 'Roger Hevey');
if (isset($query['search'])) {
$users = preg_grep("/{$query[search]}/i", $users);
}
return $users; // serializes object into JSON
} /**
* Get Charts
*
* @url GET /charts
* @url GET /charts/$id
* @url GET /charts/$id/$date
* @url GET /charts/$id/$date/$interval/
* @url GET /charts/$id/$date/$interval/$interval_months
*/
public function getCharts($id=null, $date=null, $interval = 30, $interval_months = 12)
{
echo "$id, $date, $interval, $interval_months";
} /**
* Throws an error
*
* @url GET /error
*/
public function throwError() {
throw new RestException(401, "Empty password not allowed");
}
}

让我们通过上面的TestController课程来讨论所展示的功能。首先我们来看看这个test方法。您会注意到docblock中有一种新的doc-comment标记。@url将URL映射到它下面的方法,格式如下:

@url <REQUEST_METHOD> <URL>

在这个特定的例子中,当某人在http://www.example.com/上进行GET时(假设example.com是我们的服务所在的位置),它将打印出来:

"Hello World"

这是JSON中字符串的有效表示。

继续下一个方法,login我们看到@url将任何POST映射到http://www.example.com/login到该login方法。从常规Web类型的POST获取数据与任何PHP应用程序相同,允许您将自己的验证或其他框架与此REST服务器结合使用。如果需要,也可以保留会话。虽然保持会话不是真正的REST风格,但我们通常只需要一个REST服务器来为我们的ajax应用程序提供数据,并且使用会话比使用RESTful更容易。

接下来我们有了我们的getUser方法(你会注意到我命名我的方法并不重要,因为我们的@url指令定义了哪些URL映射到方法)。你可以在这里看到几件事。首先,我们@url为此方法提供了多个映射。第二,/$id第一个URL映射有一个奇怪的地方。RestServer将任何:keyword占位符视为URL中的通配符,并将获取URL的该部分并将其传递给方法中具有相同名称的参数。在此示例中,当访问http://www.example.com/users/1234时$id将等于1234.当访问http://www.example.com/users/current时$id将等于null。您的参数的顺序无关紧要,只要它们与占位符(:id$id:username$username)具有相同的名称即可。$id = null当您有多个不需要参数的URL映射时,您还需要确保将参数设置为optional()。否则,您将抛出一个错误,告诉您没有传入必需的参数。

最后要注意的getUser是,此方法只返回一个User对象。这会被序列化为JSON(或可能是XML)并打印出来供应用程序使用。

接下来我们必须saveUser。你在这里看到我们再次有多个URL映射。这次他们还有不同的HTTP方法(POST和PUT)来创建和更新用户。这里的新东西是$data变量。这是一个特殊的关键字参数,它将包含POSTed或PUT到服务器的值。这与常规Web POST不同,它不需要只是名称 - 值对,但可以像JSON一样,发送复杂对象。例如,常规Web POST的主体,比如登录请求,可能如下所示:

username=bob&password=supersecretpassw0rd

但为我们的saveUser方法发布一个新的用户对象可能如下所示

{ “ username ”:“ bob ”,“ password ”:“ supersecretpassword ”,“ firstName ”:“ Bob ”,“ lastName ”:“ Smith ” }

因此,除了常规的Web样式POST之外,您还可以允许POSTING JSON。

最后我们得到listUsers方法。test方法简单。但$query参数是新的。此特殊参数可用于读取查询字符串。并将查询字符串参数保存为关联数组。例如,如果客户端使用url请求此API,/users?search=Manda$query参数将保持[search => Manada]

我称这些类来处理请求Controllers。并且它们可以通过URL映射,数据库配置等完全自包含,这样您就可以毫不费力地将它们放入其他RestServer服务中。

REST index.php

为了让整个服务器启动,你需要创建一个index.php文件,让你的URL重写直接请求(另一个你可以在其他地方学到的主题),然后创建RestServer并添加控制器类到它用于处理。RestServer将使用APC或文件缓存请求之间的URL映射以加速请求。如果使用自动加载和此缓存,则不必在每个请求上加载每个控制器文件,只需要请求所需的文件。缓存仅在生产模式下运行。这是一个示例index.php文件:

spl_autoload_register(); //除非我们使用它们,否则不要加载我们的类

$ mode  =  ' debug ' ; // 'debug'或'production'
$ server = new RestServer($ mode);
// $ server-> refreshCache(); //如果类在生产模式下更改,则暂时取消注释以清除缓存 $ server - > addClass(' TestController ');
$ server - > addClass(' ProductsController ',' / products '); //将此添加为此类中所有URL的基础 $ server - > handle();

而已。您可以根据需要添加任意数量的类。如果存在冲突,则稍后添加的类将覆盖先前添加的重复URL映射。addClass中的第二个参数可以是一个基本URL,它将作为给定类中URL映射的前缀,使您可以更加模块化。

您可以查看RestServer类,复制它并将其用于您自己的目的。它是在MIT许可下。要添加的功能包括XML支持和HTTP身份验证支持。如果您更好地完成此课程,请通过发表评论与大家分享您的更新。我将尝试使用新功能更新此类,因为它们是共享的。我希望你喜欢!

祝你好运,如果你最终使用它,请告诉我!

更新:我为可能需要它的人提供了一个示例.htaccess文件。它只会重写对不存在的文件的请求,因此您可以在webroot中拥有images,css或其他PHP文件,它们仍然有效。任何能给404的东西都会重定向到你的index.php文件。

DirectoryIndex index.php
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^$ index.php [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>

认证

身份验证对每个应用程序都是唯 但是将身份验证机制绑定到RestServer很容易。只需添加一个名为所有请求的方法authorizeController就会先调用该方法。如果authorize()返回false,则服务器将发出401 Unauthorized响应。如果authorize()返回true,则请求继续调用正确的控制器操作。除非您添加@noAuth操作的文档(我通常将其置于@url映射之上),否则所有操作都将首先运行授权。

在您的身份验证方法中,您可以使用PHP的getallheaders功能或$_COOKIE根据您的用户授权方式。这是您从数据库加载用户对象的位置,并将其设置为$this->user = getUserFromDatabase()以便在以后调用时您的操作可以访问它。

RestServer是一种将应用程序映射到REST API的简单机制。其余细节由您决定。

跨域资源共享

出于安全原因,浏览器限制从脚本内发起的跨源HTTP或REST请求。因此,使用来自浏览器的REST API的Web应用程序只能向其自己的域发出API请求。RestServer通过在REST index.php文件中包含以下代码,可以将覆盖此限制配置为允许交叉请求请求。

/*
* 在$ server = new RestServer($ mode)之后包含以下行;
* 或使用阵列中的多个起点的$服务器- > allowedOrigin = 阵列( ' http://example.com ', ' https://example.com ');
* 或通配符$ server - > allowedOrigin = ' * '
*/
$ server - > useCors = true ; $ server - > allowedOrigin = ' http://example.com ' ;

异常抛出错误处理

您可以通过在类中抛出一个例外来轻松地向API用户提供错误RestException。例

/ **
* 按id或当前用户获取用户
*
* @url GET / users / $ id
* @url GET / users / current
* /
public function getUser( $ id = null) {
if( $ id){
$ user = User :: load( $ id); //可能的用户加载方法
if(!$ user){
throw new RestException(404,' User not found ');
}
} else {
$ user = $ _SESSION [ ' user ' ];
}
return $ user ; //将对象序列化为JSON
};

您可以控制REST服务处理错误的方式。您可以使用添加错误控制器$server->addErrorClass('ErrorController');

此控制器可以定义命名的方法handle401handle404添加您自己的自定义错误处理逻辑。

PHP 轻量级 REST框架的更多相关文章

  1. 微博轻量级RPC框架Motan

    Motan 是微博技术团队研发的基于 Java 的轻量级 RPC 框架,已在微博内部大规模应用多年,每天稳定支撑微博上亿次的内部调用.Motan 基于微博的高并发和高负载场景优化,成为一套简单.易用. ...

  2. 轻量级ORM框架初探-Dapper与PetaPoco的基本使用

    一.EntityFramework EF是传统的ORM框架,也是一个比较重量级的ORM框架.这里仍然使用EF的原因在于为了突出轻量级ORM框架的性能,所谓有对比才有更优的选择. 1.1 准备一张数据库 ...

  3. 2016 年 50 个最佳的轻量级 JavaScript 框架和库

    作者:IT程序狮链接:https://zhuanlan.zhihu.com/p/24598210来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 回顾今年已发布的 JS ...

  4. .NET轻量级MVC框架:Nancy入门教程(二)——Nancy和MVC的简单对比

    在上一篇的.NET轻量级MVC框架:Nancy入门教程(一)——初识Nancy中,简单介绍了Nancy,并写了一个Hello,world.看到大家的评论,都在问Nancy的优势在哪里?和微软的MVC比 ...

  5. JustWeEngine - 轻量级游戏框架

    JustWeEngine - 轻量级游戏框架 An easy open source Android game engine. Github地址 引擎核心类流程图 使用方法 引入Engine作为Lib ...

  6. c# 轻量级ORM框架 实现(一)

    发布一个自己写的一个轻量级ORM框架,本框架设计期初基于三层架构.所以从命名上来看,了解三层的朋友会很好理解. 设计该框架的目的:不想重复的写增删改查,把精力放到功能实现上. 发布改框架的原因:希望给 ...

  7. C# 的轻量级 RPC 框架

    Redola.Rpc 的一个小目标 Redola.Rpc 的一个小目标 Redola.Rpc 的一个小目标:20000 tps. Concurrency level: 8 threads Comple ...

  8. 轻量级IOC框架Guice

    java轻量级IOC框架Guice Guice是由Google大牛Bob lee开发的一款绝对轻量级的java IoC容器.其优势在于: 速度快,号称比spring快100倍. 无外部配置(如需要使用 ...

  9. 轻量级IOC框架:Ninject

    Ninject 学习杂记 - liucy 时间2014-03-08 00:26:00 博客园-所有随笔区原文  http://www.cnblogs.com/liucy1898/p/3587455.h ...

  10. 如何编写轻量级 CSS 框架

    Github 地址: https://github.com/nzbin/snack Demo 演示: https://nzbin.github.io/snack/ 前言 这篇文章我已经酝酿了半年之久, ...

随机推荐

  1. VS2110。VC++编译错误"error LNK2005: 已经在 XXX.obj 中定义的问题"

    有时候我们会在头文件当中定义一些全局变量或者全局函数,这种做法会比较方便,但有时候会出现“编译错误"error LNK2005: 已经在 XXX.obj 中定义的问题"的链接问题. ...

  2. python学习之——习题一

    习题一:使用while循环输入1 2 3 4 5 6   8 9 10 (不含7) 首先想到,先使用while循环打印出1-10数字,然后再将数字“7”剔除. # 先打印出1-10 n = 1 whi ...

  3. UVA11922 Permutation Transformer

    思路 直接使用FHQ Treap维护即可 代码 #include <cstdio> #include <cstring> #include <algorithm> ...

  4. Unity 2018.2.8 旧版本安装包和破解软件

    声明:本文所提供的所有软件均来自于互联网,仅供个人研究和学习使用,请勿用于商业用途,下载后请于24小时内删除,请支持正版! 最近Unity官网下载的旧版本,都无法正常破解.此链接有之前下载的离线安装包 ...

  5. js添加的元素无法触发click事件

    动态生成的元素,使用.on绑定事件,比如$(document).on("click",".divclick",function(){})

  6. 用JS更好的实现响应式布局

    响应式布局更加高效的方法: 代码实现 <script> $(function() { (function(){ var $html = $('html'); var $window = $ ...

  7. 为wordpress后台登陆添加算术验证码

    对于新建站(个人博客-柠檬https://ninmong.com)的站长来说提高后台的安全性,是一件非常重要的事,添加验证可以起到很好的效果,废话少说,贴代码 //后台登陆数学验证码 function ...

  8. julia 安装

    https://julialang.org/downloads/ 下载安装程序,拖拽完成安装

  9. python2和python3的range(100)的区别

    python2返回列表,python3返回迭代器,节约内存

  10. 【官方下载】EasyCMDB官方基础版免费下载使用!

    链接