-
Notifications
You must be signed in to change notification settings - Fork 0
Tutorial.Others I: Module API.zh_cn
前面的章节里,将每个开发内容用比较长的篇幅作了详细的介绍,这一章将主要针对开发中还比较常见的一些问题作统一介绍,这些问题不需要太长的篇幅,因此将其汇总在一起,这章的内容主要包括:
- 模块对外接口
- 本地化
- 模块更新
- 数据缓存
- 模块对外接口
在做项目时经常会遇到模块间的数据调用,比如A模块读取B模块的数据表、A模块调用B模块的方法来处理数据。这种情况下,为了实现模块间的解耦,我们不建议在A模块里直接操作B模块的数据表或方法,而是让B模块提供一个接口让A模块调用。用这种方式,当B模块的方法或数据表结构发生变化时,只需要修改B模块的接口,而不需要更改A模块的代码。
Pi Engine提供了模块间接口调用的机制,即封装在Pi\Service\Application\Api类里,开发者只需要调用系统提供的接口并传递相应的参数即可。
1.1 创建接口类
模块的对外接口都封装在src/Api目录下的类里,默认的类为Api类,当然开发者还可以创建其他类,只是接口的调用方式会不一样。现在我们以member模块为例,创建两个Api类:Module\Member\Api\Api类和Module\Member\Api\Entity类,Api类用于返回模块的基本信息,Entity类用于读取member模块的数据表,并返回用户列表。在src目录下创建Api文件夹,并添加Api.php和Entity.php:
member
|-src
|- Api
|- Api.php
|- Entity.php
- 创建Api类
打开Api.php并添加如下代码:
路径:usr/module/member/src/Api/Api.php
Code 9.1.1
<?php
namespace Module\Member\Api;
use Pi\Application\AbstractApi;
use Pi;
class Api extends AbstractApi
{
protected $module = 'member';
public function info($field, $rawData = true)
{
$row = Pi::model('module')->find($this->getModule(), 'name');
return $rawData ? $row->$field : $row->$field ? 'Active' : 'Dactivate';
}
}
在代码里,首先定义了命名空间,由于这个接口类需要继承自Pi\Application\AbstractApi类,因此需要引用这个类。在类Api里,我们定义了$module私有变量,将赋给member模块名。接着定义了info公有方法,并带有两个参数,$field为读取core_module表的哪个字段,$rawData表示是否输出原始数据。
在info()方法里,通过调用find()方法读取core_module表里member模块的所有数据,并根据参数将最终数据返回。在page模块的IndexController/indexAction里调用接口,可以看到如下页面(接口的调用在后面章节里介绍):
图9-1 调用member模块info接口结果
- 创建非Api类
现在介绍非Api类的创建,方法和Api一致,打开Entity.php并添加如下代码:
路径:usr/module/member/src/Api/Entity.php
Code 9.1.2
<?php
namespace Module\Member\Api;
use Pi\Application\AbstractApi;
use Pi;
class Entity extends AbstractApi
{
protected $module = 'member';
public function getList()
{
$module = $this->getModule();
$rows = Pi::model('account', $module)->select(array())->toArray();
return $rows;
}
}
整个Entity类的结构与Api类一致,我们创建了一个getList()方法,将member_account表里的所有数据都读取出来,并转换成数组后返回。同样在page模块的IndexController/indexAction里调用接口,并在页面里通过调用接d()打印出来,可以看到调试信息里出现了member模块的用户数据:
图9-2 调用Entity类的getList接口得到的结果
1.2 接口调用
上一节给出了两个类,但这两个类调用的方式不一样,这里分为默认Api(Api类)调用方式和非默认Api(如Entity类)调用方式。
- 默认Api调用方式
默认Api的调用方式有两种:
Pi::service('api')->demo('test', $args);
Pi::service('api)->demo->test($args);
这两种方式的都调用了同一个方法,Pi::service('api')即实例化了Pi\Application\Service\Api对象,Pi Engine就是通过这个类作为中介进行模块间的方法调用。demo就是模块名,test为Api类里的方法,$args就是所带的参数,若有多个参数,就和普通调用一样,用逗号将参数分割开。如上一节中Api类的info()方法的调用方式就是:
$result = Pi::service('api')->member('info', 'active', false);
或
$result = Pi::service('api')->member->info('active', false);
- 非默认Api调用方式
非默认Api调用方式只有一种,不过这里的调用接口就需要指定是调用哪个类了:
Pi::service('api')->demo(array('check', 'test'), $args);
Pi::service('api')->demo(array('check', 'test'), $p1, $p2, ...);
其中,demo为模块名,check为类名,即Api目录下的Check类,test为Check类里的方法,$args为参数。第二个例子里示例了多个参数情况的调用方式,若没有参数,$args不用写,如上一节中Entity类的getList()方法的调用方式为:
$result = Pi::service('api')->member(array('entity', 'getList'));