ThinkApiAdmin 回调机制实现

ThinkApiAdmin 是糅合了thinkadmin和apiadmin的一个合体版本。均采用上述两种框架的v2版本来进行整合的。其中有一个比较重要的父类:BasicAdmin

此时仅来说一下它其中的一个父类方法:_list

/**
 * 列表集成处理方法
 * @param Query $dbQuery 数据库查询对象
 * @param bool $isPage 是启用分页
 * @param bool $isDisplay 是否直接输出显示
 * @param bool $total 总记录数
 * @param array $result
 * @return array|mixed
 * @throws \think\db\exception\DataNotFoundException
 * @throws \think\db\exception\ModelNotFoundException
 * @throws \think\exception\DbException
 */
protected function _list($dbQuery = null, $isPage = true, $isDisplay = true, $total = false, $result = [])
{
    $db = is_null($dbQuery) ? Db::name($this->table) : (is_string($dbQuery) ? Db::name($dbQuery) : $dbQuery);
    // 列表排序默认处理
    if ($this->request->isPost() && $this->request->post('action') === 'resort') {
        $data = $this->request->post();
        unset($data['action']);
        foreach ($data as $key => &$value) {
            if (false === $db->where('id', intval(ltrim($key, '_')))->setField('sort', $value)) {
                $this->error('列表排序失败, 请稍候再试');
            }
        }
        $this->success('列表排序成功, 正在刷新列表', '');
    }
    // 列表数据查询与显示
    if (null === $db->getOptions('order')) {
        $fields = $db->getTableFields($db->getTable());
        in_array('sort', $fields) && $db->order('sort asc');
    }
    if ($isPage) {
        $rows = intval($this->request->get('rows', cookie('rows')));
        cookie('rows', $rows >= 10 ? $rows : 20);
        $page = $db->paginate($rows, $total, ['query' => $this->request->get('', '', 'urlencode')]);
        list($pattern, $replacement) = [['|href="(.*?)"|', '|pagination|'], ['data-open="$1"', 'pagination pull-right']];
        list($result['list'], $result['page']) = [$page->all(), preg_replace($pattern, $replacement, $page->render())];
    } else {
        $result['list'] = $db->select();
    }
    if (false !== $this->_callback('_data_filter', $result['list']) && $isDisplay) {
        !empty($this->title) && $this->assign('title', $this->title);
        return $this->fetch('', $result);
    }
    return $result;
}

前面基本是都是数据的刷新,排序等一些方法。注意最后面几行

if (false !== $this->_callback('_data_filter', $result['list']) && $isDisplay) {
    !empty($this->title) && $this->assign('title', $this->title);
    return $this->fetch('', $result);
}

这几行代码就是实现回调机制的,回调如果用C/C++来理解的话应该是指针传值,通过指针访问函数。例如下面的代码:

void callBack(l callback)
{
    /** NULL */
}
void subCallback(char *s) 
{
    /** NULL */
} 
callBack(&subCallback);

上述代码是一段回调,如果可以理解,那么就可以继续下去。如果没有学过指针,那就不要在意了。只要知道回调函数是指的是将函数已参数的形式传递并调用就好了。

可以看到它是首先调用了callback这个函数传递了一个字符串和一个关联数组的内容,掉用完后判断一下是否等于true 并且 判断是否可以显示。那么关键的就是看看这个callback函数了。

    /**
     * 当前对象回调成员方法
     * @param string $method
     * @param array|bool $data
     * @return bool
     */
    protected function _callback($method, &$data)
    {
        foreach ([$method, "_" . $this->request->action() . "{$method}"] as $_method) {
            if (method_exists($this, $_method) && false === $this->$_method($data)) {
                return false;
            }
        }
        return true;
    }

这一句话:[$method, "_" . $this->request->action() . "{$method}"]  实际是一个索引数组。

array(2) {
  [0] => string(12) "_data_filter"
  [1] => string(18) "_index_data_filter"
}

当第二次循环到_index_data_filter的时候就可以进行调用了

 /**
     * 列表数据处理
     * @param $list
     */
    protected function _index_data_filter(&$list)
    {
        dump("www");die();
        $alert = [
            'type' => 'danger',
            'title' => '操作安全警告(谨慎刷新接口路由)',
            'content' => '新增或编辑接口后必须刷新接口路由才能正常访问!请根据实际情况刷新路由!'
        ];
        $tags = Db::name($this->table_api_group)->column('id,name');
        $handlers = Db::name($this->table_admin)->column('id,username');
        foreach ($list as &$vo) {
            $vo['tags_list'] = [];
            $vo['handler_name'] = Db::name($this->table_admin)->where('id', $vo['handler'])->value('username');
            foreach (explode(',', $vo['gid']) as $tag) {
                if ($tag !== '' && isset($tags[$tag])) {
                    $vo['tags_list'][$tag] = $tags[$tag];
                } elseif ($tag !== '') {
                    $vo['tags_list'][$tag] = $tag;
                }
            }
        }
        $this->assign(['handlers' => $handlers, 'alert' => $alert, 'tags' => $tags]);
    }

实际就是执行了上述代码。具体的执行指令就是: $this->$_method($data)php5+这种写法是允许的即直接指向一个变量,这个变量如果是函数名的话,则会直接运行这个函数。虽然运行这个函数的上下文句柄是Row.php文件,但是其实你是基于BasicAdmin这个类的。而这个函数定义在BasicAdmin类中,所以你可以进行引用。


流程:parent::_list(ROW模块) -> _callback(BasicAdmin模块 -> _index_data_filter (ROW模块)


php5+的版本中你还可以直接 new $var 。这样来初始化类,即使这个变量只存了一个类名,但是你依然可以引用。


ThinkApiAdmin 回调机制实现


本站如无特别说明即为原创,转而告知:(https://iwonmo.com/archives/1341.html)

标签: apiadmin, ThinkAdmin, ThinkPHP5, 回调机制

已有 3 条评论

  1. 隔壁老王 隔壁老王 回复 2018-07-20 19:04

    请问这程序如何安装,导入数据库后没有一张表

    1. 王And木 王And木 回复 2018-07-21 12:11

      你可以试试这个修改版:https://www.iwonmo.com/archives/1347.html

    2. 王And木 王And木 回复 2018-07-21 12:10

      直接会有一个think_api_admin的数据库

添加新评论