Download the PHP package liuxingwei/simple-api-framework without Composer
On this page you can find all versions of the php package liuxingwei/simple-api-framework. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download liuxingwei/simple-api-framework
More information about liuxingwei/simple-api-framework
Files in liuxingwei/simple-api-framework
Package simple-api-framework
Short Description A simple API framework.
License MIT
Informations about the package simple-api-framework
SAF 框架使用说明
零、概述
SAF(Simple Api Framework)
是一个极简单的PHP
API
开发框架,适用于前后端分离架构的web
项目,作为后端PHP
API
服务的框架。
说其极简,一方面是因为它只有很少的核心类和几个支持文件,另一方面是因为它只支持有限的场景,当然,也是说它非常易于使用。
SAF
没有Beautiful URL
路由,GET
请求的参数是通过形如name=zhangsan&sex=male
的QueryString
参数传递的。
SAF
遵循了惯例优于配置的理念,API
必须放在指定的目录(项目目录的Application\Api
)下,且GET
请求对应的API
类要放在Get
子目录,而POST
请求对应的API
类要放在Post
子目录,其他类型的HTTP
请求对应的API
,也放在与其HTTP METHOD
相对应的子目录。
数据库方面,SAF
有一个简单的DB
类,它是以PDO
为底层的,理论上它可以支持多种数据库服务,但是目前只在MySQL
上做过测试。因此最适合的数据库搭配就是MySQL5.7+
。
对于PHP
,由于7.2.*
和其前的版本,在trait
特性支持上有缺陷(引用继承了同一trait
的多个trait
时,会导致重复定义方法的致命错误),因此建议PHP 7.3+
。
一、环境要求
支持PHP 5.6
,建议PHP 7.3+
,MySQL 5.7+
。
二、下载
1. composer
2. github
三、环境搭建
有如下几种方式,任选其一(前两种方式仅适用于开发、测试环境):
1、PHP Built-in Server
使用PHP
内建服务时,无需nginx
、apache
,只需PHP
。
在命令行下,切换至public
文件夹(safpath
指SAF
的路径),执行php -S localhost:xxxx index.php
即可,其中xxxx
为端口号。
示例:
浏览器打开localhost:xxxx
,看到如下内容,服务启动成功:
2、借助 VSCode 中 PHP Server 插件
安装PHP Server
插件,打开File > Preferences > Settings
,找到Extensions > PHP Server Configuration
,将Relative Path
改为./public
。
如果PHP
可执行文件没加到系统路径中,可以将其填写在PHP Server
插件的PHP Path
配置项中。
打开public/index.php
文件,在文件窗口右键,选PHP Server: Server Project
。
浏览器打开localhost:xxxx
,看到如下内容,服务启动成功:
PHP Server: Stop
可以停止服务。
PHP Server: Reload Server
可以重启服务。
3、使用 WAMP
启动WAMP
,点进托盘区WAMP
图标,选择Apache > httpd-vhosts.conf
文件。
在打开的文件中,复制VirtualHost
段,修改端口,并将路径修改为项目目录的public
文件夹。
示例(safpath
即指SAF
的路径):
要复制的段:
复制后修改IP
和DocumentRoot
、Directory
路径:
修改后的完整文件:
重启Apache
。
浏览器打开localhost:xxxx
,看到如下内容,服务启动成功:
4. nginx
添加一个server
配置:
重启nginx
。
四、目录结构
初始的项目目录结构如下:
五、创建API
在application/Api/Get
或application/Api/Post
中根据业务需要创建一个子文件夹(也可以是多级文件夹),在其中创建一个API
类。
该类实现Lib\Core\Interfaces\BaseApi
接口,并实现run()
方法,该方法签名为:run(array $param):mixed
。
例如,在Get
文件夹创建Example
文件夹,并在其中创建Index.php
,文件内容如下:
run()
方法的参数即为HTTP
请求的参数集合。
此时,向服务器的/example/index
发出GET
请求,即可收到值为
的json
返回。
此时,向/example/index
发出POST
请求,收到的则是
要创建一个接受/example/index
的POST
请求的API
,需要在application/Api/Post
中创建Example
文件夹,并在Example
中创建Index.php
文件:
命名空间与uri
的关系
API
类遵循psr4
标准,其命名空间Application\Api
映射于项目根目录中的application/Api
目录。
API
类名与API
的uri
之间的关系是,将类的命名空间中的Application\Api\xxx
部分去除,并将\
转换为/
,就是该API
的uri
,而其中的xxx
即对应了HTTP METHOD
。
例如类Application\Api\Get\Example\Index
对应的API
的uri
即为/example/index
,相应的HTTP METHOD
为GET
。
而类Application\Api\Post\Example\Index
对应的API
的uri
也为/example/index
,但相应的HTTP METHOD
为POST
。
PUT
、PATCH
、DELETE
等HTTP METHOD
类推。
由于HTTP
定义的url
对于大小写不敏感,在转换为类名时,会自动将每部分的首字母转换为大写,并将短横线
及其后的一个字母转换为大写字母,以对应命名空间中的大写字母。
run()
方法的参数
run()
方法的params
参数接收了与HTTP METHOD
相对应的request
数据。
对于POST
、PUT
、PATCH
,如果提交的HEADER
中Content-Type
为application/json
的情况,接收了json
解码后的Request Payload
数据。
对于PUT
、PATCH
的application/x-www-form-urlencoded
,接收了(解析后的)Form Data
数据,类似于$_POST
的值。
对于POST
的form-data
、multipart/form-data
、application/x-www-form-urlencoded
,则接收了(解析后的)Form Data
数据。相当于$_POST
的值。
对于GET
和DELETE
,则接收了解析后的Query String
键值对。相当于$_GET
的值。
其它情况,则直接在params
的BODY
元素中存储了提交的Request Payload
的原始值。
ErrorCode
类
可以将返回的基本结构放在配置文件中,通过ErrorCode
类读取。
框架提供了一个ErrorCodeTrait
,其中定义了实例变量errCode
,实例化了ErrorCode
类,可以直接在需要使用ErrorCode
的类中使用(注意规避一下与errCode
变量名的命名冲突):
ErrorCode
使用的配置文件有default.php
和xx.php
两个,后一个文件的xx
指的是配置语言,默认为中文,即cn
。配置文件默认放在项目根目录下的conf/err_define
文件夹。
文件位置和语言均中在conf/config.php
中配置:
配置方式参见conf/err_define/cn.php
。
default.php
中放置的是系统预定义的配置,不建议直接修改,可以在语言文件中定义同名元素覆盖默认配置。
配置中的元素的key
,可以当作errCode
的属性直接使用:
可以这样改写Example\Index
:
消息定义可以使用占位符,占位符被包含在{{:
和}}
之间。可以使用数组指定要替换的与数组键匹配的值。
例如,定义如下消息:
然后在Api
的run()
方法中这样使用:
结束执行
框架最后调用API
代码就是run()
方法,因此该方法执行的最后一行代码就标志了API
的执行结束。
下面的代码示例了在不同条件下的不同输出并结束API
的执行:
默认的输出中,HTTP CODE
均为200
。
如果认为登录失败是一种错误,可以定义errorCode
的属性:
如果定义的code
和HTTP
错误码相同,还可以使用SafException
类的throw
静态方法抛异常:
这两段代码的输出是一样的。
输出类型
默认的输出类型为application/json
。无需主动对结果进行json_encode
,只需run()
方法返回要输出的数组即可。
也可以定义其它类型的输出,通过API
类的$responseType
属性指定。
可以使用的类型有:
html
、json
、xml
、text
、javascript
、steam
。
其中,json
和xml
类型,run()
方法返回数组;html
和text
返回文本;javascript
返回js
文本。
stream
用于输出文件,除了run()
方法要返回待输出文件的内容外,还需要通过headers
属性指定response
头信息。
配置文件
通用的配置文件放置在conf
目录中,文件名为config.php
,框架提供了一个示例文件config.php.sample
。
该文件内容示例如下:
其中的配置数组将被读入超全局变量$_ENV
的config
元素中。
上面示例中的变量可以这样读取:
为方便使用,该配置也被定义在CONFIG
常量中,相同的配置还可以这样读取:
通常情况下,我们的生产环境和测试、开发环境在配置方面总会有些差别,因此SAF
提供了可以覆写conf/config.php
文件中的默认配置的方法:
即在conf/env.php
文件中放置需要覆写的配置项,比如生产环境的数据库主机地址为10.0.0.1
,密码为@77pai*654
,则可以在生产服务器的conf/env.php
文件作如下配置:
而与conf/config.php
相同的配置,则无需在conf/env.php
中重复配置。
不要将conf/config.php
文件提交到版本库,可以将其放入版本库的忽略文件列表中,而额外提供一个conf/env.php.sample
,作为配置的参考。
DB
和Model
框架实现了一个基于PDO
的DB
类,具体使用请参考doc
目录的DB-Class-Usage.md
文件。
框架提供了一个BaseModel
基类,可以以此为基础自定义Model
类,继承BaseModel
类。建议将Model
类定义在Application\Model
命名空间中。
上例中,是假定表名与类名相同,都是user
(在MySQL中不区分大小写)。
如果实际的表名与类名不同,则需要使用$table
属性自定义表名:
框架会将类名定义中的大写字母转换「下划线加小写」字母的形式。
注意不要在MySQL
中用驼峰法命名表名,而要用下划线命名法。
上例也可以省略表名的显式定义:
如果使用依赖注入方式注入Model
类,建议以多实例模式注入,以避免单例引起的问题。
可以在定义Model
时即将其指定为多实例模式:
依赖注入支持
框架提供了对依赖注入的支持。使用了改造过的LIUXINGWEI/LXW-PHP-DI
(fork 自PHP-DI/PHP-DI
)。主要是增加了Scope
注解和scope()
方法,以支持非单例注入模式。
Scope
注解用于自动装配类的定义,其参数可以是singleton
或prototype
,不写Scope
注解,或者不写Scope
的参数,均默认为singleton
,即单例模式,prototype
则为非单例模式。参见Application/Model/SafExample
类的定义。
scope()
方法用于依赖注入配置,在调用factory()
方法之后,链式调用scope()
方法,其参数为singleton
或prototype
,分别对应单例和非单例模式。参见conf/config.php.sample
文件中的定义。
两种非单例注入模式的注入示例见Application/Api/Get/Example/Index
。
默认的配置文件是conf/di_config.php
,不过可以通过系统配置文件conf/config.php
中的di_config
项来修改。
该配置项可以是一个PHP-DI
配置的路径,也可以是一个包含多个PHP-DI
配置文件路径的数组。
框架在conf
目录放置了一个依赖注入配置的示例文件conf/di_config.php.sample
。
有关PHP-DI
的详细使用请查阅PHP-DI 文档。
示例API
中Get\Example\Index
中有依赖注入示例。
虚拟子目录支持
如果需要将API
部署在虚拟子目录中,需要将请求转发至public\index.php
,由其负责路由。
同时,需要修改conf\config.php
中的api_path
设置,将虚拟目录放在该参数中,例如为所有API
提供/Api
路径前缀:
AJAX 跨域问题
如果将SAF
用于AJAX
调用的API
服务,可能需要跨域。
跨域配置项如下:
enable
配置项决定了是否启用跨域。系统默认是不启用。
domain
的系统默认值为*
。
methods
的系统默认值为。
headers
的系统默认值为。
由于系统需要使用header
的默认值支持,因此此项配置不会覆盖系统默认值,而是会与系统默认值合并。其余三项,则会由用户配置覆盖系统默认值。
参数校验
框架提供了几个基本的校验类,用于对请求参数进行校验。
这些校验方法的使用依赖了annotation
(注解)技术。仅需在run()
方法上添加注解,即可实现对参数的校验。
每条注解需要声明要校验的参数名,有的还需要带有额外的参数。
已经实现的校验注解及其示例如下(所有注解的字符串类型必须使用双引号作为定界符,使用单引号会引发错误):
1. Required
Required
注解用于参数必须的情况。它只要求参数存在,对于参数值则没有要求。
如上代码要求$params
参数数组中必须包含user_name
和password
两个元素。
2. NotEmpty
NotEmpty
注解用于参数不得为空的情况。
如上代码校验参数$params
中的user_name
元素不得为空。
需要注意的是NotEmpty
注解不对参数是否存在进行校验,它仅在要校验的参数存在的情况下才有效。
如果要求参数必须存在且不得为空,需要联合Required
注解共同完成校验:
NotEmpty
支持对要校验的参数去首尾空格:
不过,trim
仅存在于校验过程中,对实际参数没有影响,因此在run()
方法内部,仍需自己处理参数的首尾空格问题。
3. 长度校验
对长度的校验有两个注解,Length
适用于字符串,Limit
适用于数值。
Length
注解有max
和min
两个可选参数,分别限制最大(含)和最小长度(含),为闭区间。
Limit
注解也是max
和min
两个可选参数,闭区间。不过它支持浮点数。
4. 正则校验类
对于电话号码、IP地址、邮编、Email等进行合法性校验时,会使用到正则表达式。
Rule
注解就用于这种场合。
与前面的校验类不同,正则校验类允许自定义校验失败时的消息,见上例中的error
参数。
自定义校验类
可以自定义校验类,具体写法可以参照Lib\Validatetions
中的预置校验类。
简单的说,校验类是依赖doctrine/annotations
实现的。
首先,自定义校验类要继承Lib\Validations\AbstractValidation
类,并在类前面添加@Annotation
和@Target({”METHOD"})
注解:
校验类须实现check()
方法,其参数即为框架转换后的请求参数(也即run()
方法接收到的参数,见前言run()
方法的参数。
在校验通过时,check()
方法返回true
,失败时返回false
。
并且在失败时,要设置err
变量,其类型为数组,包括code
和message
两个元素,对应失败的编码和原因。
校验类的蕨类定义了一个变量value
,它对应于校验注解的同名参数,如果该参数位于注解的第一位,可以不标名:
上面例子中的两种注解,其效果是一样的,在MyValidation
类中的value
获取的值均为username
。
校验类的其它公有变量,对应于注解中的同名参数。
书写注解时,要注意,如果参数类型为string
,则对应的参数值要使用双引号,而不能用单引号。如果参数类型是array
,要放在一对花括号中,其格式与标准json
基本一致。
以下是一个比较完整的示例:
不建议将自定义校验类放在Lib\Validations
命名空间,在升级框架时可能会受影响。
可以将自定义校验类放在框架可识别的任意命名空间中,并在配置文件中使用validation_namespaces
对其进行标识。上面的示例就是将校验类放在Application\Validations
命名空间中,其在配置文件中的定义如下:
All versions of simple-api-framework with dependencies
ext-pdo Version *
ext-json Version *
ext-mbstring Version *
liuxingwei/lxw-php-di Version ^6.0
doctrine/annotations Version ^1.8