SkillAgentSearch skills...

Doba

A fast, lightweight, and simple PHP development framework

Install / Use

/learn @jinhanjiang/Doba
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

程序可运行在PHP5.6+, PHP7+以上版本

一 框架结构

1 doba框架结构

|-core
|   |-AutoTask.php
|   |-BaseConfig.php
|   |-BaseDAO.php
|   |-Constant.php
|   |-Cookie.php
|   |-Plugin.php
|   |-RedisClient.php
|   |-RefreshDaoMap.php
|   |-Session.php
|   |-SQL.php
|   |-Util.php
|
|-struct
|   |-同下面的生成项目结构   
|
|-init.php
|
|-readme.md

2 项目结构(骨架)

|-autotask
|-cache
|-callback
|-common
|   |-config
|   |   |-config.php
|   |   |-namespace.php
|   |   |-varconfig.php
|   |
|   |-libs 
|   |   |-dao
|   |   |-map
|   |
|   |-plugin
|   |   |-Web      
|   |   |   |-BaseController.php
|   |   |
|   |   |-BasePlugin.php
|   |   |-PaginationPlugin.php
|   |   |-RpcPlugin.php
|   |   |-WebPlugin.php
|   |      
|   |-rpc
|
|-doba
|-mgr
|   |-同以下web
|-mgr.php
|
|-vendor
|-web
|   |-controller
|   |   |-DefaultController.php
|   |
|   |-lang
|   |   |-en.php
|   |   |-zh.php
|   |   
|   |-views
|   |   |-default
|   |   |   |-index.php
|   |   |   
|   |   |-header.php
|   |   |-footer.php
|   |
|-index.php

3 自动加载类映射

引用对象的时候,根据包名区分

\Doba    => [项目]/doba/core/
\Doba\Dao\db1    => [项目]/common/libs/dao/db1/
\Doba\Map\db2    => [项目]/common/libs/map/db2/
\Doba\Rpc   => [项目]/common/rpc/

除框架自定义对象命名空间,还会支持自定义,在commmon/plugin/namespace.php中添加,例如:

return [
'Doba\Helper' => ROOT_PATH."common/config/helper",
'Doba\TraitLib' => ROOT_PATH."common/config/trait",
];

底层还会自动加载扩展中命名空间类方法,例如在commmon/plugin/Excel扩展,

<?php

namespace Doba\Plugin\Excel;

class PHPExcelReadFilter {

}

框架也支持composer引入第三方扩展,在项目index.php同级执行 composer require xxx:xx 引入相关扩展

二 快速构建项目

1 引入Doba框架

git clone https://github.com/jinhanjiang/doba

2 生成项目开发骨架

配置访问站点

例如: 要做一个博客站点,首先要在本地配置好一个能访问到的站点

a 项目目录:
/data0/website/blog

b 域名 http://blog.xxx.com 指向到项目目录

c 引用doba框架到项目目录下 /data0/website/blog/doba

d 通过url初始化项目骨架
http://blog.xxx.com/doba/init.php?a=init

执行以上步骤后。生成项目结构

三 配置多数据库链接

Doba框架支持多个数据库链接, 并快速生成DAO操作表结构

1 在/data0/website/blog/common/config/下, 创建varconfig.php

当用开发环境,和正式环境区分时,使用常量配置,可解决不同环境配置不同的问题

<?php
$GLOBALS['CONSTANT_DB_CONFIGS'] = [
    'db1'=>[
        'dbHost'=>'192.168.0.1',
        'dbName'=>'testdb1',
        'dbUser'=>'root',
        'dbPass'=>'123456',
    ],
    'db2'=>[
        'dbHost'=>'192.168.0.2',
        'dbName'=>'testdb2',
        'dbUser'=>'root',
        'dbPass'=>'123456',
    ],
];

2 或者在/data0/website/blog/common/config/config.php中配置

注意:这里配置了两个数据库链接, 这里的db1, db2要注意,会生成的表命名空间

例如:

# db1下面有一张Account表,在实例化对象的时, 其中的`\Db1`, 是上面配置中的db1设置

$account1 = \Doba\Dao\Db1\AccountDAO::me()->finds(array('selectCase'=>'*', 'limit'=>1));

# db2下面Account表
$account2 = \Doba\Dao\Db2\AccountDAO::me()->finds(array('selectCase'=>'*', 'limit'=>1));

3 创建好数据库链接后。生成DAO及MAP数据库表映射

问:为什么生成DAO和MAP
答:生成DAO文件,可支持对表数据的,增(insert),删(delete),查(finds, get),改(change)操作, 
生成MAP是生成数库表的字段映射,生成insert, update, select的sql语句时,可对传入的表字段进行验证

生成表映射的时候,如果分多张表,有些表不生成映射可设置规则,默认以 下划线数字(例如_0), 或 数字结尾的表,不生成映射

如果要修改规则,可在/data0/website/blog/common/config/config.php中设置

# 设置以_test的表不生成DAO和MAP
class Config extends \Doba\BaseConfig {
    ...

    public function initDaoMapConfig() {
        $initDaoMapConfig = parent::initDaoMapConfig();
        return array(
            'IGNORED_TABLES'=>array('/^\w+_\d+$/i', '/^\w+\d+$/i', '/_test$/i'),
            'IGNORED_TABLES_PREFIX'=>array('/^db_/'),
            ) + $initDaoMapConfig;
    }

    ...
}

在Config类中可重写父类的方法,用于更改底层配置

4 执行刷新表结构操作

每次执行,如果DAO存在不会覆盖,MAP文件每次会覆盖为最新结构

# 访问地址
http://blog.xxx.com/doba/init.php

四 项目开发

1 默认请求到index.php这个文件中, 经过判断后, 请求最后交给到

访问:
http://blog.xxx.com

请求到
/data0/website/blog/web/controller/DefaultController.php

其中的DefaultController.index方法处理

2 通过URL定位页面

http://blog.xxx.com/index.php?a=blog.pageList

可以看到结尾是a=blog.pageList

所以可以在controller下找到 BlogController.php

其中BlogController.pageList处理这个请求

在views目录下有blog这个目录,且目录下有page-list.php这个文件渲染页面效果

如果a后面的参数没有点(.),默认请求到DefaultController下, 例如a=login

五 多语言

在生成的例子中,已有多语言的配置

设置多语言在,/data0/website/blog/web/lang目录下

en.php

<?php
return array(
'Hi'=>'Hi',
'Hi, %1, welcome to the website developed by the %2 php framework.'=>'Hi, %1, welcome to the website developed by the %2 php framework.',
);

zh.php

<?php
return array(
'Hi'=>'您好',
'Hi, %1, welcome to the website developed by the %2 php framework.'=>'你好, %1, 欢迎访问由%2 php框架开发的网站。',
);

页面中显示多语言

<p>{{ @Hi }}</p>
<p><?php echo langi18n('Hi'); ?></p>
// 以上英语显示:Hi, 中文显示:您好

<p><?php echo langi18n('Hi, %1, welcome to the website developed by the %2 php framework.', 'Cheech', 'Doba')?></p>
// 如果翻译中包含要替换的变量,可使用以上方法
// 以上中文输出:你好, Cheech, 欢迎访问由Doba php框架开发的网站。

六 数据库增删改操作

前面我看看到可以通过 Dao来查询数据库, 其实Dao主要封装了,对数据库的(增,删,查,改)的操作,下面我们来看一下如何操作

数据库链接默认有个超时时间(3600s 1小时),当超过超时时间,再次执行SQL会报:MySQL server has gone away, Doba框架已做处理,会自动重连并执行未成功的sql

1 增加数据到数据库

# 以上面的AccountDAO为例,创建数据
\Doba\Dao\Db1\AccountDAO::me()->insert(
    array(
        'username'=>'doba', 
        'password'=>'123456',
        'source'=>1,
        'otherId'=>12345,
        'name'=>'doba',
        'nick'=>'xiao ming',
        'createTime'=>date('Y-m-d H:i:s'),
    )
);

如果已经存在相同记录,忽略当前新数据(有唯一主键值的数据,在表中存在)

# 可以在DAO中重写insert方法
class AccountDAO extends BaseDAO {
    ...

    public function insert($params) {
        /*
         * 在这里也可以初始化一些其他的默认值,后面在调用当前方法就不再再传了
         *  例如: 创建时间(createTime) 
        return parent::insert([
            '_INSERT_IGONRE'=>true, 
            'createTime'=>date('Y-m-d H:i:s')
        ] + $params);
         */

        return parent::insert(['_INSERT_IGONRE'=>true] + $params);
    }

    ...
}

2 删除数据库数据

通过主键删除

\Doba\Dao\Db1\AccountDAO::me()->delete(1);

echo \Doba\Dao\Db1\AccountDAO::me()->sql(); // 查看执行sql

解释:通过查看\Doba\BaseDao.php可以知道, 数据库表当中有一个主键(primary key), 在创建表结构时,可自定义,Doba框架默认为这个值为id, 当然你的表结构不是这个值,可以初始化Dao的时候修改这个值

通过多个条件删除

\Doba\Dao\Db1\AccountDAO::me()->delete(array('source'=>1, 'nameLike'=>'doba'));

\Doba\Dao\Db1\AccountDAO::me()->delete(array()); # 删除所有数据

传入数组条件,格式请看下面finds条件传参格式

3 查询数据库数据

同上面(2解释),传入值为主键值

\Doba\Dao\Db1\AccountDAO::me()->get(1);

当然如果你的表当中有,其他唯一键判断,可查出一条数据,可自行封装一个方法, 例如

class AccountDAO extends BaseDAO {
    ...

    public function getBy($params)
    {
        if(isset($params['id'])) return parent::get((int)$params['id']);

        $plus = array();

        // source 和 otherId 保证数据库查询唯一值
        if($params['source'] && $params['otherId']) {
            $plus['source'] = $params['source'];
            $plus['otherId'] = $params['otherId'];
        }

        // 如果有其他条件,可以再加

        $objs = count($plus) > 0 ? $this->finds(array('limit'=>1) + $plus) : array(); 
        return isset($objs[0]) ? $objs[0] : NULL;
    }

    ...
}

除了 查询单条数据,使用finds方法可以查出多条数据,及通过多个条件查询

# 相等查询

\Doba\Dao\Db1\AccountDAO::me()->finds(
    array(
        'username'=>'doba', 
    )
);
# SQL语句: SELECT * FROM `Account` WHERE 1=1 AND `username`='doba'

还可以这样写
\Doba\Dao\Db1\AccountDAO::me()->finds(
    array(
        'username'=>array('value'=>'doba'), 
    )
);
# SQL语句: SELECT * FROM `Account` WHERE 1=1 AND `username`='doba'

可以看到上面使第二个查询传入的值为数组,可以设置多个条件

# 数据可传值
array('and'=>true, 'op'=>'=', 'value'=>'')
  • and 默是(true), 意思是,在拼接语句时用AND, 当然这里传false, 拼接用OR
  • op 默认是(=)等于,字段名后面的操作符是等于
  • value 实际传入的值,可以传入( integer、float、string 或 boolean 的变量 ) 不能传入 ( array、object 和 resource , NULL )

其中op,有多种传值方式

[eq =], [geq, >=], [gt, >], [leq, <=], [lt, <], [<>, !=], in, nin(not in) ,like, [custom]

我来拿实际的例子来看一下

# 自定义查询
\Doba\Dao\Db1\AccountDAO::me()->finds(
    array(
        'name'=>array('op'=>'custom', 'value'=>"`name` LIKE '%doba%' OR `nick` LIKE '%doba%'"),
    )
);
# SQL语句: SELECT * FROM `Account` WHERE 1=1 AND (`name` LIKE '%doba%' OR `nick` LIKE '%doba%')


# 条件查询
\Doba\Dao\Db1\AccountDAO::me()->finds(
    array(
        'name'=>array('op'=>'like', 'value'=>"doba"), 
    )
);
# SQL语句: SELECT * FROM `Account` WHERE 1=1 AND `name` LIKE '%doba%')

当'name'=>array('op'=>'like', 'value'=>"doba%"), 
# SQL语句: SELECT * FROM `Account` WHERE 1=1 AND `name` LIKE 'doba%')


\Doba\Dao\Db1\AccountDAO::me()->finds(
    array(
        'source'=>array('and'=>false, 'op'=>'in', 'value'=>"1,2,3"),
    )
);
# SQL语句: SELECT * FROM `Account` WHERE 1=1 OR `source` IN (1,2,3)

\Doba\Dao\Db1\AccountDAO::me()->finds(
    array(
        'id'=>array('op'=>'in', 'value'=>"1,2,3"),
    )
);
# SQL语句: SELECT * FROM `Account` WHERE 1=1 OR `id` IN (1,2,3)

\Doba\Dao\Db1\AccountDAO::me()->finds(
    array(
        'id'=>array('op'=>'gt', 'value'=>"100"), // gt 可以换成 > 是相同的效果
    )
);
# SQL语句: SELECT * FROM `Account` WHERE 1=1 AND `id`>'100'

上面讲到了传值通过数组来,拼接条件,接下来讲一下通过字段后缀来拼条件, 这样操作比较简洁

\Doba\Dao\Db1\AccountDAO::me()->finds(
    array(
        'idGt'=>100,
    )
);
# SQL语句: SELECT * FROM `Account` WHERE 1=1 AND `id`>'100'

\Doba\Dao\Db1\AccountDAO::me()->finds(
    array(
        'idIn'=>"1,2,3",
        'orderBy'=>'id DESC',
        'groupId'=>'source',
        'limit'=>5,
    )
);
# SQL语句: SELECT * FROM `Account` WHERE 1=1 OR `id` IN (1,2,3) GROUP BY source ORDER BY id DESC LIMIT 5

可以发现,通过字段名 + 后缀[ Gt, In , Like, Geq, Leq, Lt, Neq] 来达到相关查询, 更多方法,可以自已尝试一下

小技巧, 数据库有很多的数据,要全部更新, 但不同的条件更新不同的值可以这样写


$lastId = 0; $limit = 100;
while (true) {
    $objs = \Doba\Dao\AccountDAO::me()->finds(
        array(
            'selectCase'=>'id,otherId', 
            'source'=>1, 
            'idGt'=>$lastId, 
            'orderBy'=>'id ASC', 
            'limit'=> $limit
        )
    );
    if(($ct = count($objs)) > 0)
    {
        foreach($objs as $obj)
        {
            // 这里是很行数据,根据条件处理(修改,删除)

        }
        if($ct < $limit) break;
        $lastId = $obj->id,
    }
    else
    {
        break;
    }
    usleep(mt_rand(500, 2000000));
    // 脚本执行太长时间,数据库链接可能会断掉,可以用下面语句重连数据库
    \Doba\Dao\AccountDAO::me()->resetdb();
}

4 更新数据库数据

通过主键更新数据

\Doba\Dao\Db1\AccountDAO::me()->cha

Related Skills

View on GitHub
GitHub Stars8
CategoryDevelopment
Updated5mo ago
Forks1

Languages

PHP

Security Score

82/100

Audited on Nov 1, 2025

No findings