《细说PHP》第四版 样章 第23章 自定义PHP接口规范 8
23.5.2 架构详解
本例的实现最重要的就是服务层的设计,有两个配置文件config.php和api.php,其中文件config.php是全局的配置文件,用于整个程序全局需要的参数设置。可以根据程序扩展需求,在配置文件中增加新的配置选项。config.php文件的内容如下所示:
本例配置文件采用PHP常量和数组两种格式,直接加载这个文件,常量就可以在任意位置使用,数组也可以作为全局变量直接在程序中使用。这个配置文件中包含了项目根目录“S_ROOT”和程序根目录“DS”两个常量,以及一个多维数组$configs。可以通过改变数组中的元素值,配置数据库的连接信息,以及改变和客户端匹配的“token”字符串。
配置文件api.php一定要根据程序相关的规则,添加路由记录,不能是任意格式的。因为路由主程序会用这个文件中设置好的路由规则匹配当前的URL,来选择控制器去处理请求,给客户端返回响应消息。api.php添加的部分路由规则示例如下:
在WebAPI中,控制器(Controller)是用来操作HTTP请求的,控制器里的“action” 方法对应不同的HTTP请求。当WebAPI收到一个HTTP请求时,路由表就会将请求映射到对应的“action”方法中。路由表的定义需要根据WebAPI的访问需求,一条条自行添加。当WebAPI框架收到HTTP请求时,它会尝试从路由表的模板中匹配一个URL,如果是重复的路由规则,会使用最前面的那一条,如果不匹配将会显示给用户错误响应消息。我们注册的这个模板规则说明如下:
Ø Router 是路由类名,通过我们定义路由类的静态方法实现路由匹配和映射机制。
Ø Router::get()是路由类中定义的用户请求方法,可以是get、post、put、delete和resource中的一个。其中,resource方法默认注册了一系列用户请求的路由规则,如果是一些通用的请求操作,只使用这一个方法注册,通用的操作请求如增、删、改、查等路由策略都可以实现。其他的方法则都是一条记录对应路由的一个请求。
Ø 路由方法中第一个参数是资源名称,需要自定义这个名称,目的是用来设置不同的URL,从而定位到不同的资源。这个名称是一个字符串,例如,"/users"、"/users/{id}"、"/users/create"、"/users/{id}/edit"等,用户请求“GET http://api.itxdl.cn/v1/users/2”时,使用的就是资源"/users/{id}"。
Ø 路由方法中第二个参数是控制器的类名和操作方法。例如,“UserController”就是用户自定义的控制器类名称,如果不是使用Router类中的resource方法,而是使用单个的get或post等方法时,需要在这个参数中,控制器类名的后面使用“@”指定这个控制器中自定义的一个方法名称。这样就可以根据用户请求,映射到指定控制器的方法中了。如果是使用Router类中的resource方法,则不用“@”指定具体的方法,因为在Router类中默认注册了所有通用默认映射方法的匹配规则。
Ø 路由方法中第三个参数是可选参数,指定API的版本号,默认是V1。按RESTful API规范, API的URL都需要有版本号对应。
Ø 路由方法中第四个参数也是一个可选参数,指定一个中间件(自定义类Middleware)的方法名称,用来对用户请求API进行安全验证。这个安全验证的规则,可以通过在Middleware类中自定义方法进行验证,只需要将方法名称字符串传入这个参数即可。在默认情况下,如果不使用该参数,则不需要进行安全验证。
设计WebAPI最主要的操作就是从用户发起请求开始,到接口服务运行后再返给用户结果。请求和响应在框架中分别通过两个类实现,在request.php和response.php两个文件中声明。在request.php中声明的Response类,用来获取用户请求API的URI和参数,根据用户的动作才能通过路由定位到具体的资源位置,并映射到指定的控制器中去处理业务。request.php文件中的代码如下所示:
通过在主入口文件index.php中,直接调用Request类中的init()方法,获取用户请求的全部信息,并应用在路由等类中,使用Request类中的getMethod()方法获取用户的请求动作,通过getUri()方法获取请求的URI信息,还能通过all()方法得到一个数组,获取全部用户请求的信息。
API服务执行后,需要返给用户信息。不管是成功执行,还是在中间某个环节出现了问题,都需要给用户一个明确的响应,而且响应信息按RESTful API的规范,格式需要统一,这样方便用户接到响应信息后能进行规范的处理。response.php文件中的代码如下所示:
在Response类中只提供success()和error()两个对外调用的方法,返回的数据消息格式是相同的,使用JSON格式向用户返回数据。消息中有4个元素,“code”是响应消息的状态码,“message”是提示用户的消息,“time”是当前服务器的时间,通过时间的变化用于区分不同时间相同的两次操作,“data”是以多维数组形式返给用户的数据。当向用户响应成功的消息时,调用本类中的success()方法,主要在控制器的方法中使用。需要两个可选参数,如果调用时没有提供参数,默认返回的状态码为“0”表示成功,并返回空数据,默认提示“success”。第一个参数需要传递一个数组,作为响应给用户的数据。第二个参数可以自定义提示用户的响应消息。 当任何一个环境出现问题时,都可以调用error()方法响应给用户错误消息提示,可以在路由、中间件、控制器、数据访问模型等类中使用,也有两个可选参数,第一个参数是状态码,默认为“E001”。本类也提供了一组常见的返回状态码和对应的错误消息,用于标准的错误消息提示。如果使用的状态码在本类中已经存在,则返给用户这个状态码和这个状态码对应的错误提示消息,如果状态码在本类中不存在,可以返给用户自定义的状态码和自定义的错误消息。
公开的API可以不用进行安全验证,但非公开的API必须通过安全验证才能访问。本例通过middleware.php文件实现一个中间件环节,专门处理用户连接验证。该文件中声明一个类Middleware,在该类中每声明一个方法就是一个验证规则,在api.php文件的路由表的每条记录中,最后一个参数传入Middleware类任意一个方法名,就可以选择使用一种验证规则。本例只在Middleware中提供一个login()验证方法。middleware.php文件中的代码如下所示:
Middleware类中的login()验证方法,用来处理用户连接时的安全验证。算法和前面安全验证章节介绍的一样,通过时间戳参数、token和用户提供的应用参数,进行排序再加密处理,得到一个“key”,再和客户端通过URL传递过来的使用同样算法的“key”进行比对,如果相同则才允许连接。
WebAPI框架最核心的功能就是路由的实现,本例通过在router.php文件中声明的Router类实现了路由的功能。当WebAPI框架收到用户的HTTP请求时,它会尝试从api.php定义的路由表中匹配模板中的每条规则信息,调用中间件进行连接验证,再映射到对应的控制器方法,如果不匹配则会响应错误消息。router.php文件中的代码如下所示:
路由类Router其实只有一个对外公开的run()方法,在主入口文件index.php中,调用完Request类的init()方法,并处理完成用户请求后就可以直接调用。在run()方法中直接加载api.php导入路由表,其实在api.php中的路由表记录,每一条就是完成一次对Router类中一个方法的调用,例如Router::get()、Router::put或Router::resource等,而且这些方法的内部,又都是通过调用本类中addRouter()方法进行路由注册的。在addRouter()方法中,通过正则匹配获取用户的请求动作和资源,再调用中间件进行安全连接验证,最后通过调用本类的toAction()方法,映射到具体的控制器,以及控制器中对应的操作方法,实现整个路由过程。
WebAPI框架的入口是index.php文件,可以将它看作一个中央调度器。程序通过URL重写规则或其他方式,把所有URL导向本文件,由它调度其他代码。index.php文件中的代码如下所示:
因为index.php是整个程序的入口文件,所以会将配置文件,以及程序需要的类文件都直接加载进来,然后调用Request类中的init()方法,获取用户所有的请求参数,再通过调用Router类的run()方法,根据用户的请求完成路由机制的处理。
《细说PHP》第四版 样章 第23章 自定义PHP接口规范 8的更多相关文章
- 《细说PHP》第四版 样章 第二章 PHP的应用与发展 1
<细说PHP>第四版 样章 第二章 PHP的应用与发展 1 学习任何编程语言之前,先了解一下它的应用与发展是很有必要的.从Web开发的历史看来,PHP.Python和Ruby几乎是同时出现 ...
- 《java编程思想(第四版)》第一二章学习笔记
目录 一.Introduction 1.抽象过程 2.面向对象语言(包括Java)的五个基本特性 3.每个对象都提供服务 4.public.private.protected三者的区别 5.Java的 ...
- 《细说PHP》 第四版 样章 第二章 PHP的应用与发展 5
2.5 如何学习PHP PHP以其简单易学的特点,以及敏捷开发的优势,从一个几乎不被人知的开源项目,慢慢成长为技术人员首选的动态Web设计工具,与其他语言相比,PHP表现得更好.更快.更简单易学.尽 ...
- 《细说PHP》第四版 样章 第23章 自定义PHP接口规范 11
23.6 使用第三方接口服务实例 接供服务的第三方接口平台有很多,现在的项目中也经常用到一些第三方接口,如支付宝.微信.短信.邮件接口等,我们需要借助第三方的能力来实现产品的某些功能.如果自己已经掌 ...
- 《细说PHP》第四版 样章 第23章 自定义PHP接口规范 9
23.5.3 WebAPI框架应用 程序框架其实就是一个半成品项目,在应用框架时,核心的服务程序只应用,不需要改动.当然如果有必要,也可以根据项目的需要对框架进行二次开发.本节内容主要基于我们的框架 ...
- 《细说PHP》第四版 样章 第23章 自定义PHP接口规范 6
23.4 API的设计原则和规范 API是服务提供方和使用方之间对接的通道,前面我们设计的一些简单API的例子,基本上比较随意,没有使用任何规范.设想一下,每个平台都可能存在大量的API,如果API ...
- 《细说PHP》第四版 样章 第23章 自定义PHP接口规范 3
23.2 接口实现的基础 大家都很了解函数在本地应用,通过名称调用函数执行,并通过传递不同参数,函数有不同执行,执行后给调用者返回结果.如果把一个函数做成一个接口远程访问,也需要这几个步骤.使用HT ...
- 《细说PHP》第四版 样章 第23章 自定义PHP接口规范 1
如今的项目开发中,接口是很普遍的应用技术.现在好多项目组都单独设有接口开发人员.像腾讯.微博.淘宝等开放平台,其所谓的开放,就是提供一些可调用的接口,用于获取相关的信息.例如,微信用户基本信息.淘宝店 ...
- 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 12
18.9 管理表books实例 在Web项目中,几乎所有模块都要和数据表打交道,而对表的管理无非就是增.删.改.查等操作,所以熟练掌握对表进行管理的这些常见操作是十分有必的.本例为了能更好地展示PD ...
随机推荐
- hadoop搭建的前期准备
这个hadoop的搭建是以比赛前的练习为目的的,所以我直接以root用户来搭建hadoop,主要也是方便我自己以后复习用的 需要的软件:vmware15.5,xshell6,xftp6,jdk Lin ...
- Eureka集群
Eureka集群搭建 高可用集群配置 当注册中心扛不住高并发的时候,这时候 要用集群来扛: 普通操作 我们再新建两个module microservice-eureka-server-2002 m ...
- 二维数组中的查找(剑指offer_4)
给定一个二维数组,其每一行从左到右递增排序,从上到下也是递增排序.给定一个数,判断这个数是否在该二维数组中. Consider the following matrix: [ [1, 4, 7, 11 ...
- vue.js 的 vue-element-admin 实践开发
官方网址: https://panjiachen.github.io/vue-element-admin-site/zh/ 一:面包屑导航,根目录文字修改: 定位到文件 vue-element-sup ...
- HTML连载53-网易注册界面实战之content的头部、content注册信息
一. 这次完成了content部分的右边图片以及content的top部分的边角填充 <!DOCTYPE html> <html lang="en"> &l ...
- Python 从入门到进阶之路(六)
之前的文章我们简单介绍了一下 Python 的面向对象,本篇文章我们来看一下 Python 中异常处理. 我们在写程序时,有可能会出现程序报错,但是我们想绕过这个错误执行操作.即使我们的程序写的没问题 ...
- 02-java性能调优-JVM内存模型详解
JVM整体结构与内存模型之间的关系 JVM整体结构图如下: 先贴一个代码: package com.jvm.jvmCourse2; public class Math { public static ...
- 发布方式一:发布.netcore流程
通过注册世纪互联,发布网站 注册需要上传身份证正反照片,以及打款一元,试用期一个月 https://www.azure.cn 注册完成后,进入主页面: 如图所示,创建完成后的效果: 点开详情, ...
- PlayJava Day012
今日所学: /* 2019.08.19开始学习,此为补档. */ JPanel和JFrame 1.JFrame是最底层,JPanel是置于其面上,同一个界面只有一个JFrame,一个JFrame可以放 ...
- Set a Many-to-Many Relationship设置多对多关系 (EF)
In this lesson, you will learn how to set relationships between business objects. For this purpose, ...