Skip to content

Tutorial.Others I: Module API.zh_cn

linzongshu edited this page Jul 4, 2013 · 2 revisions

English

前面的章节里,将每个开发内容用比较长的篇幅作了详细的介绍,这一章将主要针对开发中还比较常见的一些问题作统一介绍,这些问题不需要太长的篇幅,因此将其汇总在一起,这章的内容主要包括:

  • 模块对外接口
  • 本地化
  • 模块更新
  • 数据缓存
  1. 模块对外接口

在做项目时经常会遇到模块间的数据调用,比如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里调用接口,可以看到如下页面(接口的调用在后面章节里介绍):

fig9-1

图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模块的用户数据:

fig9-2

图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'));
Clone this wiki locally