商派 ONex_b2b2c 框架开发手札(一)- 概述

由于是国内框架,框架是很大很全,功能很多,但是一点都谈不上精美。

光看文档的组织,根本就不能够满足最基本的开发要求,大部分还是的脑补,于是,补完之后还是得乖乖连文档也补一下。

权当是开源精神帮助官方写文档。


在这里,有必要先列一个提纲,因为研究得比较快,要点也比较散乱。

  1. 安装 b2b2c 环境
    • 使用 php5.6 + Nginx + Zend Guard Loader 的基础配置
    • 处理好的 Docker 镜像
  2. 开发目录 /custom 的配置
  3. 反射 ego.php 的类库
  4. 创建并启用 app
  5. 使用 controller 和路由创建视图层
  6. 使用 dbschema 创建数据库表
    • 目录结构
    • 定义语法
    • 映射到数据库
  7. 创建 model 类
    • 目录结构
    • 创建与 dbschma 对应的模型
    • 调用方式
    • 直接编写 SQL 语句
  8. 创建 /myapp/lib 下面的工具类
    • 目录结构
    • 创建指定的工具类
    • 单例模式
    • 调用方式
  9. 后台 desktop 应用创建
    • permission
    • panelgroup/adminpanel
    • workground/menugroup/menu
  10. 模板开发
    • 模板渲染模型
    • 自定义模板
    • 模板语言
      • <{$variable}> 变量引入
      • <{if $case}><{/if}> 条件语句
      • <{foreach from=$list item=val name=key}> 循环
      • <{include}> 引入模板
      • <{require}> 引入主题模板
      • <{pagers}> 分页
      • <{assign}> 语句
      • <{im shop_id=$shop_id type=small}> 标签?在会员商品列表中出现过(估计是 QQ 控件)

安装 b2b2c 环境

使用

首先,我们开发的基础就是拿到的商派框架代码,b2b2c 的一个压缩包,然后我们第一步需要让它跑起来。

重要的事情说三遍:opcache 不能开,opcache 要关掉,opcache 不能开!!!!

下表是 php -m 得到的需要安装的模块列表:

[PHP Modules]
bcmath
bz2
calendar
Core
ctype
curl
date
dba
dom
ereg
exif
fileinfo
filter
ftp
gd
gettext
hash
iconv
json
libxml
mbstring
mcrypt
mhash
mysql
mysqli
openssl
pcntl
pcre
PDO
pdo_mysql
Phar
posix
readline
Reflection
session
shmop
SimpleXML
soap
sockets
SPL
standard
sysvmsg
sysvsem
sysvshm
tokenizer
wddx
xml
xmlreader
xmlrpc
xmlwriter
Zend Guard Loader
zip
zlib

[Zend Modules]
Zend Guard Loader

如果使用 docker,可以尝试在 php 容器内部的 /usr/local/etc/php/conf.d 下面添加 ZendLoader 的库引入。


创建并启用 app

首先,其实框架里面对 /custom 目录的支持不可谓不粗糙,导致我在开头掉进坑里转了好久。

ATTENTION: 如何才能避免掉进这个坑

切记!开发全程切勿将应用目录 myapp 放到 /custom 里面,正确的使用方法是,一直将 myapp 目录放在 /app 目录下面,直到上线之后,进后台启动这个 app,再用 ./cmd update 进行更新,然后再将 app 目录移动到 /custom 下面,否则 app 根本不能在注册器中出现!

创建一个 app 文件夹(此处用 sysmyapp),注意,要么使用 sys 开头,要么使用 top 开头来命名你的 app。

然后里面按照文档编写一个 app.xml,最精简的例子大概如下:

<!-- file: /app/myapp/app.xml -->
<app>
    <name>我的APP</name>
    <type>service</type>
    <author>
        <name>Alfred Huang (呆滞的慢板)</name>
        <email>57082212@qq.com</email>
        <url>https://www.huangwenchao.com.cn</url>
    </author>
    <version>0.1.0</version>
    <license>MIT license</license>
</app>

注意上面的 <type> 节,可以选择 service 或者 site,如果是纯逻辑和数据,请使用 sys 开头命名你的 app,这里的 type 填写 service;否则使用 top 开头命名,这里的 type 填写 site文档链接


使用 dbschema 创建数据库表


创建 model 类

目录结构

创建与 dbschma 对应的模型

类继承自 dbeav_model,例如:

class myapp_mdl_article extends dbeav_model {
}

调用方式


创建 myapp/lib 下面的工具类

目录结构

myapp 目录下创建 lib 文件夹,每一个工具类创建一个 php 文件,可以创建下级的目录。

注意命名规范,例如 /app/sysclearing 下面的内容是一个很好的例子:

lib
├── data
│   └── clean.php
├── finder
│   └── settlement.php
├── settlement.php
└── tasks
    └── settlement.php

那么会展开成这些类:

  • sysclearing_data_clean
  • sysclearing_finder_settlement
  • sysclearing_tasks_settlement
  • sysclearing_settlement

创建指定的工具类

按照上面的命名方式即可创建工具类,注意一个文件仅包含这个类的定义,不要包含其他代码。

阅读系统里面定义的其他一些 app 之后,发现基本上采用单例模式,并没有继承自其他的系统基类,内部基本上仅定义各种 function,(注意 public 要显式声明,protected 要以单下划线开头,private 要以双下划线开头)。

单例模式

在工具类的定义惯例上面,这里基本使用单例模式,关于静态类和单例模式的比较,可以参考:

http://stackoverflow.com/q/519520/2544762

http://stackoverflow.com/q/137975/2544762

对于单例模式的调用,管理上使用如下的语法:

kernel::single('____classname____')

后台 desktop 应用创建

http://club.ec-os.net/doc/b2b2c-dev/300.principles/4.conventions/2.desktop-Developer%27s+Guide/100.dev.md

permission

panelgroup/adminpanel

这部分配置下的菜单会显示在右上角的《控制面板》页面下面。

注意,icon 的目录其实应该是 /public/myapp/images/bundle 的路径开始算,这点略坑。

workground/menugroup/menu


如何分页

首先,在页面 view 里面可以嵌入标签:<{pagers data=$pagers}>,这样就可以输出所有分页的 markup。

那么我们来看一下如何在对应的 controller 上下文里面构造这个 $pagers

首先我们可以在对应的 Controller 里面定义一个私有方法 __pages()

sysmyapp_ctl_example extends topc_controller {

    // ...

    /**
     * 分页处理
     * 
     * @param $current int 当前页数(编号从 1 开始)
     * @param $filter array 除开翻页参数之外,当前查询集的其他条件(querystring 的字典)
     * @param $count int 查询集全集的项目数
     * @param $action string 列表页面不带参数的 action 字符串,例如 `sysmyapp_ctl_example@articleList`
     * @return array 返回 pagers 标签适配的分页对象格式。
     */
    private function __pages($current, $filter, $count, $action) {
        $current = $current ? $current : 1;  // 当前页面序号
        $filter['pages'] = time();  // 这个用作 nonce
        $limit = @$this->limit ?: 10;  // 每页多少个

        $totalPage = $count ?
            ceil($count / $limit - 1e-5) : 0;

        $pagers = array(
            'link'=>url::action($action, $filter),
            'current'=>$current,
            'total'=>$totalPage,
            'token'=>time(),
        );
        return $pagers;
    }

    // ...

}

然后在当前页面的 action 函数上下文里面,先根据实际情况构造好 $current $filter$count 的值,然后将其放入上下文,即可使用。

systest_ctl_example extends topc_controller {

    // ...

    /**
     * 实际的列表页面 action
     * 
     * @return mixed HTTP 响应对象
     */
    private function articleList() {

        $current = @intval(input::get('current')) ?: 1;  // 当前页面序号
        $limit = @$this->limit ?: 10;  // 每页多少个
        $offset = ($current - 1) * $limit;
        $filter = array(
            'author_id' => userAuth::id(),
            'status' => 'ACTIVE',
        );

        $modelArticle = app::get('sysmyapp')->model('article');  // sysmyapp_mdl_article

        $count = $modelArticle->count($filter);

        $pagedata['pagers'] = 
            $pagers = $this->__pages($current, $filter, $count, 'sysmyapp_ctl_example@articleList');

        $pagedata['pagers'] = 
            $articles = $modelArticle->getList('*', $filter, $offset, $limit);

        return $this->page('sysmyapp/article/list.html', $pagedata);  // 构造响应并输出,这是基类 topc_controller 的方法
    }

    // ...

}

直接编写 SQL 语句

如果我们要编写一些复杂的查询结构,我们可以先构造一个底层的 database() 对象,然后在上面就提供了底层的 SQL 执行方法。

我们可以通过任意一个 model 对象的 database() 方法产生数据库访问对象,然后通过 executeQuery($sql) 方法执行查询。

执行的结果通过 fetch() 或者 fetchAll() 方法就可以得到想要的结果。

// 这里随便拿一个 model 类,其实什么都行
$db = app::get('sysshop')->model('shop')->database();

$result = $db.executeQuery("
    select * from sys_shop
    where id < 10000;
")->fetchALL();

So easy,如果不需要返回整个结果表,只需要第一行,将上面的 fetchAll 换成 fetch 即可。

关于上传图片路径的问题

通过这个方法来获取图片前端的路径

kernel::get_host_mirror_img()

【转载请附】愿以此功德,回向 >>

原文链接:https://www.huangwenchao.com.cn/2016/03/onex-b2b2c-1.html【商派 ONex_b2b2c 框架开发手札(一)- 概述】

发表评论

电子邮件地址不会被公开。 必填项已用*标注