PhalApi是一款国人制作的PHP纯后端框架。它的开发相当简单,同时也具备文档生成等特色功能。下面,我通过简单的几点,让你可以快速入门使用该框架的开发。

建议使用PHPStorm作为IDE,代码提示相当完全。由于PHP的热更新特性,修改过的PHP文件保存后立即生效,无需编译,无需重启服务器。

什么是PhalApi

安装PhalApi

Composer是PHP的包管理器(类似于Java的Maven、node的npm)。

Composer的安装请参考https://pkg.phpcomposer.com/#how-to-install-composer,不要在英文官网直接下载安装包。

Composer安装后请立即切换到国内源https://developer.aliyun.com/composer。

Phar是PHP界的Jar包,可以像Jar包一样引入即用。

在项目目录下执行composer create-project phalapi/phalapi即可创建PhalApi项目,项目路径为./phalapi。

若需要安装阿里云OSS的SDK,则在项目路径下(注意cd到phalapi目录)按https://help.aliyun.com/document_detail/85580.html说明调用Composer。

composer require aliyuncs/oss-sdk-php

composer install

本地调试环境配置

建议使用傻瓜式一体化软件XAMPP搭建本地的调试环境。

修改XAMPP中Apache的配置文件,找到这两行:

DocumentRoot "X:/XAMPP/htdocs"

将引号内目录修改到PhalApi项目的public目录,注意使用左斜杠替换右斜杠、

修改后启动Apache,则项目在localhost:80上启动。如需修改端口请参考Apache配置文件的其他配置项。

更优雅的接口地址

默认的接口网址为类似于http://xxx.com/?s=App.User.Login(?s后为接口全限定名),不够美观。开启URI路由匹配后可以实现http://xxx.com/User/Login的接口路径,比较美观。(App字段可以省略)

开启方式:

在./config/sys.php修改enable_uri_match配置为true

撰写服务器Rewrite规则。若使用Nginx服务器,请直接参考官方文档示例(http://docs.phalapi.net/#/v2.0/how-to-request?id=开启uri路由匹配)。

若使用Apache服务器:

在./public目录下新建规则文件.htaccess

写入下列内容(即将所有404请求转发到index.php,作为一个controller)RewriteEngine on

RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^(.*)$ index.php

重启Apache服务器

PhalApi的ADM三层模型

有别于软件开发领域常用的MVC三层模型,在后端纯接口开发中,View层显然没有任何意义。所以PhalApi采用了创新的ADM三层模型。

A - Api接口层,只负责接受请求、调度Domain层、发送响应

D - Domain领域层,最关键,负责业务逻辑的处理

M - Model数据层,只负责与数据库的交互。注意,它不仅描述Object的基本信息,还要实现一些会与数据库交互的方法。类似于JavaEE中的Bean定义+DAO层

Api接口

三层模型所有的代码均在./src/app目录下。Api、Domain、Model目录下默认生成了一些demo,可以删除。

在Api目录下新建php类,假设为MyClass.php。注意下列要求:

namespace App\Api; - 命名空间。注意,必须限定到MyClass.php所在目录。即如果MyClass.php放在./src/app/Api/Mobile下,则namespace App\Api\Mobile。

use PhalApi\Api; - 要求使用Api类。

class MyClass extends Api - 所有类都要继承自Api类。

在类中定义的一系列public的函数,就是一个个实际的接口(注意,不是类是接口,而是类的成员函数是接口!所以这个类是起到了接口分类的作用)

接口的返回格式永远是JSON,形式为 {ret, data, msg},其中ret是HTTP状态码,msg是错误提示信息,而data就是我们的业务数据。在函数中return的关联数组会自动转化成JSON,注入data。例如

下面介绍接口的调用网址,假设函数名为hello,类文件为MyClass.php

MyClass路径

接口URL

./src/app/Api/MyClass.php

XXX.com/MyClass/hello

./src/app/Api/Mobile/MyClass.php

(正确)XXX.com/Mobile_MyClass/hello

./src/app/Api/Mobile/MyClass.php

(错误)XXX.com/Mobile/MyClass/hello

即若类文件在Api目录下发生了层叠,则需要加入下划线分隔,而不是一直用斜杠。

下面介绍如何在Api层获取和处理请求参数。

重写public function getRules()方法,

public function getRules() {

return array(

'[FUNCTION NAME]' => array(

'[PARAM NAME]' => array('name' => '...', 'require' => ..., 'type' => '...', 'source' => '...', 'desc' => '...', 'min' => ..., 'max' => ...)

);

}

返回一个关联数组,键为该Api类下的函数名称(即接口),值又是一个关联数组,键为参数名,值又是一个关联数组,用于进行该参数的配置,具体配置项可参考http://docs.phalapi.net/#/v2.0/api-params。下面介绍几个常用的:

name:string,前端请求时用的参数名

require:boolean,是否必须

type:参数类型,可以用string、int等

source:string, 参数源,可以用post、get(注意小写)等

desc:参数说明,该说明会出现在自动文档中

min和max(均可选):当type是int时,可以起到后端参数校验的作用

在接口对应函数的代码中取参数:

$param_var = $this->[PARAM NAME]

取好参数,发给Domain层的对应函数,获取返回值,发送响应给服务器端。这就是Api层做的事。

一般来说,需要在头部use一下App\Domain下的对应的Domain,然后在需要时new一个domain对象来使用。

Model模型

在Model目录下新建php类,假设为User.php。通常的开发习惯是,数据库一张表对应一个Model类,这样可以实现对表的描述(类似于Mybatis与POJO的配合)。以MySQL为例,注意下列要求:

namespace App\Model; - 同样要严格限定到User.php目录

use PhalApi\Model\NotORMModel as NotORM; - 要求使用NotORM类。NotORM是PhalApi内部的封装的MySQL交互引擎

class User extends NotORM - 模型类必须继承NotORM

protected function getTableName($id) {

return 'user_score';

}

重写protected function getTableName($id)方法(注意函数签名带参$id),返回值是该模型对应的表名。

现在即可在User类下编写各个CURD功能的函数,函数参数是进行SQL查询需要参数。具体使用请参考官方文档http://docs.phalapi.net/#/v2.0/database-usage。整体风格是链式调用,例如:

首先要通过$this->getORM()获取NotORM实例,然后组织相关SQL关键字即可。

值得一提的是,NotORM的功能非常的强大(起到了SQL语句Builder的作用,极大地避免了直接组织SQL语句),它甚至可以接收关联数组为参数进行各种智能的INSERT、UPDATE等操作。具体使用请参考http://docs.phalapi.net/#/v2.0/database-usage,靠这里的一两句话是说不清道不明的。

如果有需要,NotORM也支持执行原生SQL语句。

Domain领域

在Domian领域下新建php类,假设为User.php。对于Domain类,要求比较简单:

namespace App\Domain\; - 你懂的

没了。

Domain类不要求use框架内部的类,也不要求定义的类继承相关类。

在User类下写相关业务函数即可。一般来说,此处函数的参数是Api层请求需要的所有参数。

在业务函数中,调用Model层中封装好的有关CURD函数,完成业务逻辑。一般来说,需要在User.php头部use一下App\Model下的对应的User的model,在进行CURD操作时,new一个model对象来使用。

全局配置文件

在./config目录下的app.php、dbs.php、di.php、sys.php就是四大全局配置文件。

如何在./src中脚本的任意位置取出其中配置的键值对?PhalApi用了依赖注入(DI)和反射的功能,实现了看起来非常Java的方式来获取。

例如在app.php中配置了如下内容:

'token' => array( 'SALT' => 'imsalt', 'expire' => 7200)

要取盐值,则取法为\PhalApi\DI()->config->get('app.token.SALT')。

即对于这四大配置文件,均用\PhalApi\DI()->config->get来访问,参数为配置项的全限定名。

这四大配置文件的作用是:

app.php - 用户自定义的相关配置均追加于此

dbs.php - 数据库相关配置

di.php - 依赖注入相关配置,当有新组件插入时需要修改

sys.php - 系统级配置,例如是否调试、URI匹配等

全局功能函数

如何定义一个在./src中任何位置都可以调用的功能函数?把这个函数的实现写在./src/functions.php中即可。在需要调用时,使用\App\[FUNCTION NAME]来调用。

自动接口文档

不同于Swagger的高侵入性,PhalApi的自动接口文档系统非常的简单优雅。不仅方便前端阅读,还具备自解释性,利于后续后端的维护。和JavaDoc类似,它全部依靠多行注释完成。并且,多行注释内允许使用基本的HTML标签,如来加粗等等。

注意,合法的多行注释格式如下,首行有两个星号。

/**

*

*/

这样使用:

在Api层的每个类文件的use \PhalApi\Api;下行进行注释,用于说明该类的整体作用

在getRules函数内进行的相关参数配置会自动反映到接口文档中

在接口对应函数的正上方进行注释,用于说明该接口的作用。语法如下:

第一行写接口名称

@desc后写接口描述(description)

@return后写接口返回值描述,@return [type] [name] [description]

如果不想要该接口被自动文档扫描,则添加@ignore

若一切配置无误,则可以在http://xxx.com/docs.php阅读到自动生成的接口文档。

接口文档网页还可以进行定制:

修改./public/docs.php中的$projectName,可以修改左上角LOGO处的标题。

如果需要公共说明(如图中的统一说明),则在./public/docs.php末尾添加php脚本闭标签(?>)后,可以书写HTML代码。由于该页面布局的原因,不建议将公共说明写在头部。

前端请求方式

对于PHP后端,前端在发送POST请求前必须设置如下请求头,否则后端收不到数据:

header: {'content-type': "application/x-www-form-urlencoded; charset=UTF-8"}

​GET请求没有类似限制。

前端用axios来POST时,data为Object,无需stringify

前端收到的响应作res.data后即为如下结构的Object:

{

"ret": 200,

"data": {

...

},

"msg": ""

}

​ ret为http状态码,msg为错误提示信息(当状态码非200时才有),data为业务数据

在自动接口文档中,形如App.X_Y.Z的接口请求地址为http://xxx.com/X_Y/Z(如果配置了URI匹配)

开发实例

我们以一个简单的接口为例(获取表中分数最高的n个记录),展示一下PhalApi下一个接口的开发过程

这是一个公共接口,用于手机端。故在./src/app/Api/Mobile下新建PHP类文件Other.php

进行namespace、use的基本配置,让Other类继承Api。编写类文件注释用于生成文档。注意此处use...as...别名的使用。

重写getRules方法,接受一个参数n,函数名是getTopN

写getTopN函数以及相关文档注释。注意,接口函数都不需要参数,而是在内部获取。

开始开发Domain层。在./src/app/Domain/Mobile下新建PHP类文件Other.php

进行namespace的配置,写业务逻辑代码(当n>5时视为n=5处理)。可以看到返回的是一个响应体。所以在Api层是直接return的。注意此处同样使用了别名use \App\Model\Mobile\Other as ModelOther;

显然该业务需要与数据库交互,所以需要开发Model层。在./src/app/Model/Mobile下新建PHP类文件Other.php

进行namespace和use配置,Other类继承NotORM类。重写getTableName($id)方法

实现getTopN($n)方法。注意,此处SQL查询的结果会自动转为关联数组传到Domain层,Domain层再向上传到Api层,Api层响应时关联数组就自动变成JSON结构注入到响应体的data中了,多么美妙!

至此,一个接口开发完成。相应的文档也已经自动生成了。

系统日志

PhalApi提供了一个简单日志系统。它将日志等级分类三级:error、info、debug。

保存目录:./runtime/log

调用方式:\PhalApi\DI()->logger->error/info/debug([日志内容], [上下文描述(可选)])

MySQL数据库

MySQL数据库需要在./config/dbs.php内配置。

PhalApi支持实现多库集群、分库分表。具体请参考:

服务端请求CUrl

如果有需要在服务器端利用服务器发送HTTP请求(例如小程序开发中的code2session),PhalApi为我们封装了CUrl库来实现,非常简单。参考http://docs.phalapi.net/#/v2.0/curl。

缓存体系

PhalApi支持许多种缓存。

此处用常用的Redis说明。

在./config/di.php中向$di注入Redis依赖:

$redis_config = array('host' => '127.0.0.1', 'port' => 6379);

$di->cache = new PhalApi\Cache\RedisCache($redis_config);

之后,在需要使用Redis的地方利用\PhalApi\DI()->cache->set/get/delete等等即可

CORS跨域

利用跨域插件https://github.com/gongshunkai/phalapi-cors,配置相当简单。

RESTful

由于PHP只是Apache/Nginx上的插件,HTTP服务是由它们提供的,所以若要实现严格的RESTful API,必须借助它们的支持。例如Apache,需要对.htaccess文件进行配置,来转发/重定向请求,将RESTful的请求转化为传统的。

上线部署

PHP项目的部署非常简单,上传代码就完事了!将整个phalapi目录上传到服务器上,然后确保你在远端服务器上也进行了全文开头的操作:

Apache默认文档路径指向./public

配置好了Rewrite规则

此刻,你的接口就部署完成了。当然,你应该考虑一下:

真实上线,文档不能让别人随意看到!请备份后删除./public/docs.php

删除无用的./sdk和./tests目录

【全文终,谢谢您的阅读!】

phalapi可以依赖注入么_PhalApi 2.7 开发快速上手相关推荐

  1. phalapi可以依赖注入么_phalapi-进阶篇8(PhalApi能带来什么和进阶篇总结)

    #phalapi-进阶篇8(PhalApi能带来什么和进阶篇总结) ##前言## 先在这里感谢phalapi框架创始人@dogstar,为我们提供了这样一个优秀的开源框架. 到今天位置PhalApi已 ...

  2. phalapi可以依赖注入么_phalapi-进阶篇2(DI依赖注入和单例模式)

    phalapi-进阶篇2(DI依赖注入和单例模式) 前言 先在这里感谢phalapi框架创始人@dogstar,为我们提供了这样一个优秀的开源框架. 离上一次更新过去了快两周,在其中编写了一个关于DB ...

  3. phalapi可以依赖注入么_[7.8]-phalapi-进阶篇2(DI依赖注入和单例模式) | PhalApi(π框架) - PHP轻量级开源接口框架...

    phalapi-进阶篇2(DI依赖注入和单例模式) 前言 先在这里感谢phalapi框架创始人@dogstar,为我们提供了这样一个优秀的开源框架. 离上一次更新过去了快两周,在其中编写了一个关于DB ...

  4. Swift中依赖注入的解耦策略

    原文地址:Dependency Injection Strategies in Swift 简书地址:Swift中依赖注入的解耦策略 今天我们将深入研究Swift中的依赖注入,这是软件开发中最重要的技 ...

  5. PHP进阶学习之依赖注入与Ioc容器详解

    背景 在很多编程语言(例如java)开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,一旦有修改,牵扯的类会很多 ...

  6. dagger2 注入_使用Dagger 2在GWT中进行依赖注入

    dagger2 注入 依赖注入是一种软件开发概念,其中为对象提供了创建所需的所有对象或值. GWT用户已经熟悉GIN,但已经不推荐使用此工具,因此不再支持它,因此使用GIN的应用程序当前确实需要告别. ...

  7. 使用Dagger 2在GWT中进行依赖注入

    依赖注入是一种软件开发概念,其中为对象提供了创建所需的所有对象或值. GWT用户已经熟悉GIN,但已不推荐使用此工具,因此不再支持,因此使用GIN的应用程序当前确实需要告别. Dagger是GWT的新 ...

  8. php对象依赖注入作用,php面向对象依赖注入理解及代码举例分析解释

    依赖注入是通过类的构造函数.方法.或者直接写入的方式,将所依赖的组件传递给类的方式.一般通过构造函数注入的是强依赖关系的组件,setter方式用来注入可选的依赖组件. 现在,大多数流行的PHP框架都采 ...

  9. Spring-初识Spring框架-IOC控制反转(DI依赖注入)

    ---恢复内容开始--- IOC :控制反转 (DI:依赖注入) 使用ioc模式开发 实体类必须有无参构造方法 1.搭建Spring环境 下载jar http://maven.springframew ...

  10. Java依赖注入(DI)实例详解

    Java依赖注入模式允许我们摆脱硬编码,使我们的应用更加松耦合.增强扩展性以及可维护性.通过依赖注入我们可以降低从编译到运行时的依赖性. Java依赖注入 Java的依赖注入仅仅通过理论是很难解明白的 ...

最新文章

  1. python培训班那家好-Python培训机构去哪好
  2. ROC 曲线和 AUC 值
  3. Py之pandas:pandas的read_excel()函数中各参数说明及函数使用方法讲解
  4. 查看mysql进程--show processlist
  5. Java学习笔记_类和对象
  6. Python---寻找给定序列中相差最小的两个数字
  7. java.lang.Math类的API介绍
  8. k-center 聚类
  9. php 实现两变量值对换,PHP互换两个变量值的方法(不用第三变量)
  10. IOS开发-关于自定义TabBar条
  11. 带格式文本html 直接复制粘贴,通过JS将带格式的文本复制到剪贴版的两种方法...
  12. 第九届河南理工大学算法程序设计大赛 正式赛(部分题解)
  13. CentOS 7 配置免密码证书登录
  14. Linux fork函数
  15. 豆瓣评论【数据集分享】
  16. 微软私有云的数据保护之神——DPM
  17. MyEclipse详解
  18. 2021-2027全球与中国零售空间规划软件市场现状及未来发展趋势
  19. 宝塔面板专业版企业版教程 纯手动 带原版脚本 插件免费用
  20. Java Swing快速构建窗体应用程序

热门文章

  1. Python项目:爬取智联招聘网站的数据分析职位信息并进行可视化分析
  2. youtube-dl 环境搭建 使用
  3. 神经网络的参数(Weight)
  4. Python | pandas 计算每行的增长率与累计增长率
  5. waves服务器系统盘,Waves Soundgrid服务器(DIY)
  6. NeHe OpenGL教程 第十三课:图像字体
  7. atomic java_Java中Atomic类的使用分析
  8. 全球37%手机或因芯片漏洞遭攻击、黑客利用微软漏洞窃取登录凭据|11月25日全球网络安全热点
  9. Unrecognized Windows Sockets error: 10106: Socket creation failed
  10. oracle清空实例数据,Linux下删除oracle实例