# 如何开发接口
使用PhalApi专业版开发接口,非常简单,大致流程如下。
## 目录结构
PhalApi Pro版的目录结构如下,
```
./
├── README.md # 简介
├── bin # 脚本目录
├── config # 配置目录
│ ├── app.php # 应用配置
│ ├── dbs.php # 数据库配置
│ ├── di.php # 依赖服务配置
│ └── sys.php #系统配置
├── data # 数据库
│ └── phalapi_pro.sql # 数据库安装时的文件
├── language # 翻译包
├── pro_admin # 管理后台的前端源代码,基于iview-admin
├── pro_platform # 开放平台的前端源代码,基于iview-admin
├── public # 对外访问的目录
│ ├── admin # 管理后台访问入口(相当于pro_admin打包构建后的dist目录)
│ ├── api # 接口访问入口(内分前台API和后台API)
│ ├── docs # 离线生成的HTML接口文档
│ ├── docs.php # 在线版接口文档访问入口
│ ├── index.php
│ ├── init.php # 全局初始化文件
│ ├── install # 安装向导(成功安装后建议删除此目录)
│ ├── platform # 开放平台访问入口(相当于pro_platform打包构建后的dist目录)
│ ├── static # 静态资源
│ ├── uploads # 上传目录(需要有写入权限)
│ └── wiki # 技术文档
├── runtime # 运行目录
│ ├── _install.lock # 安装锁定文件
│ ├── cache # 文件缓存
│ └── log # 文件日志
├── sdk # SDK包
├── src # 项目源代码,非常重要
│ ├── admin # 后台接口源代码(遵循ADM模式)
│ ├── app # 开放平台接口源代码(遵循ADM模式)
│ ├── base # 基础包源代码(放置底层公共的代码,不对外直接提供接口,即不提供Api层)
│ ├── platform # 开放平台接口源代码(遵循ADM模式)
│ ├── task # 计划任务接口源代码(遵循ADM模式)
│ └── view # 页面模板目录(如接口文档)
├── tests # 单元测试
└── vendor # composer包,不需要手动修改,通过composer install/update可进行安装和更新
```
PHP代码层次结构如下:

## 编写Api接口层
如果需要编写开放接口,可以在./src/app/Api目录下新增一个PHP文件,类名和文件名一样(需要区分大小写)。并继承App\Common\Api基类即可。
例如开放接口的Hello World示例,接口文件是:./src/app/Api/HelloWorld.php,类名是:App\Api\HelloWorld,对接的接口服务名称是:App.HelloWorld.Say。
```php
array(
'nickname' => array('name' => 'nickname', 'desc' => '昵称'),
),
);
}
/**
* 示例
* @desc 第一个前台接口示例
*/
public function say() {
$nickname = $this->nickname;
return array('content' => 'Hello world!');
}
}
```
保存后,访问接口文档列表,可以看到以下新接口:

同时在接口详情文档可以查看到相应的详细接口文档:

如果需要编写后台接口,则需要放置在./src/admin/Api目录下,并继承Admin\Common\Api基类。其他开发要求类似。
> 温馨提示:以下方法是系统保留的函数名,不以用于接口函数名称,否则会影响接口正常运行。系统保留接口函数名称有:tryToGetUid()、checkUserLogin()、tryToGetAppKey()、checkAppOnline()、getCurContext()、init()、createMemberValue()、getApiRules()、getApiCommonRules()、getRules()、filterCheck()、userCheck()、isServiceWhitelist()、equalOrIngore()。
## 如何取消接口令牌验证?
默认情况下,前台接口需要进行```access_token```令牌验证,以保护接口不被非法请求。如果不需要对指定的接口进行验证,可以在配置文件./config/app.php中的service_whitelist白名单中添加接口。例如上面的HelloWorld接口不需要接口验证,可以在最后追加配置:
```php
'service_whitelist' => array(
'Site.Index',
'HelloWorld.Say', // 追加Hello World示例白名单
),
```
接口白名单配置,会取消过滤器,不进行任何校验和判断,此时不会相应调整应用的接口权限。如果需要让接口权限在界面上显示保持一致,可以配置接口权限规则。
> 温馨提示:配置接口白名单,开放平台和管理后台的接口权限显示不会影响。
## 如何取消接口权限判断?
+ 如何取消全部接口权限判断?
可以修改./config/app.php里面的default_app_api_rigths_is_allow配置项为true,即可让开放接口默认拥有权限,相当于取消全部接口权限判断。
+ 如何取消某个接口类的接口权限判断?
在你的接口具体子类中,重载```\App\Common\Api::userCheck()```方法,不进行任何操作即可。
```php
/**
* 平台接口基类
*/
class Api extends \App\Common\Api {
/**
* 进行接口权限判断
* @throws BadRequestException
*/
protected function userCheck() {
// 不需要
}
}
```
> 温馨提示:通过代码取消接口权限判断,开放平台和管理后台的接口权限显示不会影响。
+ 如何取消一个接口的接口权限判断?
在你的接口具体子类中,重载```\App\Common\Api::userCheckActionWhitelist()```方法,返回不需要进行接口权限判断的接口白名单。
```php
温馨提示:通过代码取消接口权限判断,开放平台和管理后台的接口权限显示不会影响。
## 如何获取当前上下文信息?
如何获取当前上下文、登录会员ID和app_key?
在App\Common\Api接口基类中,已经封装了针对于当前上下文、登录会员ID和app_key等接口,方便项目快速开发。
以下是使用代码和相关说明。
```php
class HelloWorld extends Api {
public function say() {
// 获取会员ID,未登录时异常返回
$uid = $this->tryToGetUid();
// 获取会员ID,未登录时返回0
$uid = $this->tryToGetUid(false);
// 检测会员是否已登录,未登录时异常返回
$this->checkUserLogin();
// 获取app_key,未指定时异常返回
$appKey = $this->tryToGetAppKey();
// 获取app_key,未指定时返回空字符串
$appKey = $this->tryToGetAppKey(false);
// 检测是否已指定app_key
$this->checkAppOnline();
// 获取当前上下文
$context = $this->getCurContext();
var_dump($context->getUid()); // 会员ID
var_dump($context->getAppKey()); // app_key
}
}
````
## 如何隐藏access_token参数?
如果不需要在接口文档上显示```access_token```参数,可以在接口参数规则里这样配置(设置is_doc_hide为true即可)。
```php
class HelloWorld extends Api {
public function getRules() {
return array(
'say' => array(
'accessToken' => array('name' => 'access_token', 'is_doc_hide' => true),
),
)
}
}
```
## 编写Domain领域层
Domain领域层主要用于封装复杂的业务逻辑、规则和算法。此部分PHP代码放置在./src/app/Domain目录下。此部分根据不同项目的业务需求,具体开发即可。
## 编写Model数据层
Model数据层主要用于操作MySQL数据库,全部的Model子类可继承Base\Model\Base基类,此基类封装了很多实用的方法和接口,极大减少了数据库封装的代码。例如对应配置表的配置Model类代码如下:
```php
array('App', '新的顶级命名空间'),
```
例如,加了Task命名空间后:
```php
// 开放接口的命名空间,配置后可提供接口权限分配,可配置多个
'open_api_namespaces' => array('App', 'Task'),
```
在管理后台可以自动管理该命名空间下的接口权限。
接口权限分配:

接口服务列表:

在开放平台,开发者也可自动看到新增命名空间下的接口。

## 如何隐藏接口?
和开源版一样,在接口类或方法中添加```@ignore```注释。
如:
```php
'Hello PhalApi Pro!');
}
}
```
## 如何开启接口参数加密传输?
为了保护客户端传递的参数不被外界非法获取,除了使用HTTPS协议外,也可以通过代码方式来增加。
在PhalApi专业版,你可以:
** 客户端RSA公钥加密传输API接口参数 + 服务端RSA私钥解密API接口参数。**
### 重要配置
首先,是RSA私钥和公钥的文件,分别是:
+ rsa私钥文件:./config/phalapi_pro_rsa.pri
+ rsa公钥文件:./config/phalapi_pro_rsa.pub
在项目启动或开始时,你可以更换以上RSA配置文件,项目开始使用后,不建议再更换。
其次,还可以开启./config/app.php配置文件中的encrypt_data公共参数,方便客户端查看可以传递此参数以及其格式要求说明。
```php
/**
* 应用接口层的统一参数
*/
'apiCommonRules' => array(
'accessToken' => array('name' => 'access_token', 'default' => '', 'desc' => '访问令牌,仅当开启签名验证时需要传递,生成令牌可使用App.Auth.ApplyToken接口'),
/** ----- 如果你需要使用第二套加密算法,请开启以下参数规则 ----- **/
// 'app_key' => array('name' => 'app_key', 'default' => '', 'desc' => 'app_key,用于区分客户端应用,首次接入需要创建应用并等待管理员审核通过'),
// 'sign' => array('name' => 'sign', 'desc' => '动态签名,签名算法是: