二次开发文档:开发入门

二次开发入门须知

什么是二次开发

二次开发,简称二开,就是在现有的CMS框架上进行开发和修改、功能的扩展,然后达到自己想要的功能,一般来说都不会改变原有系统的内核。


为什么要二次开发?

现有功能无法满足你的需求时,需要自己写一些代码来实现功能。



二次开发的开发人员需要具备的基本条件

1. 具备基本的PHP知识(必备);

2. 具备HTML知识,了解css和js最佳(必备);

3. 具备SQL语句知识(必备);

4. 有PHP框架开发经验最好,CI框架、ZF框架、TP框架,Yii框架等(可选);

5. 有服务器配置相关技术的(可选)。


如果你不具备这些知识,请务必提前学习,否则用起来会比较吃力。


一、本地开发环境推荐

1、Xp.cn的phpstudy集成环境

2、BT 面板


二、开发编辑器推荐

1、Phpstorm

2、NotePad++

3、SublimeText


二次开发须知阅读:https://www.xunruicms.com/doc/491.html

二次开发须知(必读)

二次开发是非常方便的,代码清晰,入门简单。

开发者不要盲目的去修改系统核心代码,这样会导致无法正常的升级CMS,导致无法及时获得CMS安全补丁。


建站和二次开发时建议不要变动代码的目录如下:

{xunruicms_img_title}

(红色部分是宸逸CMS的核心程序,每次升级宸逸CMS时只需要升级这些文件夹即可)


建站和二次开发时,不要修改系统本身的程序文件,建议开发者使用新建控制器、新建模型的方式做新增功能或者功能变更,这样就避免CMS升级时的功能覆盖。

宸逸CMS模块是采用继承式控制器开发,这样可以避免不变更系统目录(以上标红的目录),将业务逻辑代码写到模块本身的控制器之中,不会影响升级。

需求大的情况下建议联系官方寻求开发方案,切勿盲目的修改系统代码,导致CMS效率降低,后期无法正常升级CMS补丁。


无论是自己的站还是给自己客户的站,都建议开发者定期为网站更新补丁,不要嫌麻烦,这是对自己负责,也是对自己客户的负责。


如果非要修改系统文件怎么办


如果非要修改系统文件,你可以找官方提出申请,把你的想法提交给官方,官方审核之后,认为你这个想法可行,那么官方会给你重新开辟一个二次开发的端口。

官方联系方式:q@xunruicms.com


目录结构

宸逸CMS系统文件结构

{xunruicms_img_title}

public

网站主目录,如果没有这个目录表示根目录是网站主目录

api 或 public/api

接口调用入口、编辑器等

cache

缓存文件目录,可自定义位置,例如使用固态硬盘

config

用户的一些自定义配置、自定义函数、自定义钩子等

dayrui

系统核心程序目录,可移动目录

static 或 public/static

资源目录,css、js、图片和网站样式文件

template

模板文件目录,可自定义位置

uploadfile 或 public/uploadfile 

附件上传目录,可自定义位置




dayrui目录

App

应用程序目录、自定义应用、自定义插件、自定义模型

Fcms

宸逸CMS程序类目录,此目录的文件不允许修改

ThirdParty

第三方类的程序文件



开发者模式-开发工具配置

开启开发者模式,全站都可以看到调试信息,一般用于:

插件开发/二次开发时、做模板界面时、出现URL重定向过多时、性能调试时、系统故障排查时。

开发者模式-开发工具配置



开启方法:网站根目录文件./index.php

将IS_DEV设置为1,网站上线之后请关闭此项。

开启后会比较直观的看到程序错误的情况。

IS_DEV = 1是表示开启,方便开发者调试;

开发完成可以改成0,关闭调试模式,进入生产环境!




网页底部有一个【火苗图标】表示开发者工具的调试器图标:

image

Database: 本页面查询sql记录

Files:加载的文件数

views:本页的模板文件,以及可用的模板变量

Routes:不用点击,已经屏蔽

Events:加载的钩子数

History:历史访问记录

Vars:本页面可用的系统变量


创建应用程序

在二次开发时,首先要创建自己的应用程序目录,如下图所示的Test目录:

blob.png

应用程序目录

./dayrui/App/应用程序名。

命名方式

应用程序目录由英文字母组成,目录首字母必须大写。

文件结构

/Test
        /Config     配置存储配置文件
        /Controllers   控制器文件
        /Helpers     函数文件
        /Libraries    类文件
        /Models      模型文件,操作数据库
        /Views      后台的显示视图文件,html模板


demo程序下载: http://help.xunruicms.com/Test.zip  


示例程序使用方法

1、Test目录放到 /dayrui/App/Test/ 目录之下


2、前台访问地址: /index.php?s=test&c=home&m=index

对应控制器:dayrui\App\Test\Controllers\Home.php


3、用户中心访问地址: /index.php?s=member&app=test&c=home&m=index

对应控制器:dayrui/App/Test/Controllers/Member/Home.php


4、后台管理访问地址: /admin.php?s=test&c=home&m=index

对应控制器:dayrui/App/Test/Controllers/Admin/Home.php


定义控制器

视频操作方法:

https://www.xunruicms.com/doc/video-dev-%E5%88%9B%E5%BB%BA%E6%8E%A7%E5%88%B6%E5%99%A8%E7%9A%84%E6%96%B9%E6%B3%95.html


程序路由模式格式为:

前端控制器:/index.php?s=模块目录&c=文件名&m=方法名&参数名=参数值
会员控制器:/index.php?s=member&app=模块目录&c=文件名&m=方法名&参数名=参数值
后台控制器:/admin.php?s=模块目录&c=文件名&m=方法名&参数名=参数值
系统API控制器(系统保留部分不允许开发):/index.php?s=api&c=文件名&m=方法名&参数名=参数值


创建好应用程序之后才能创建控制器。

如下是一个基础控制器类的例子。在CMS中,所有的控制器都继承了控制器基类。

dayrui/App/Test/Controllers/Home.php

路由访问

/index.php?s=test&c=home&m=index

自定义路由地址

开发者可以自定义路由的访问URL,配置文件根目录/config/rewrite.php(/表示根目录)

#在[]内部增加下面代码,表示/test.html指向本控制器
'test.html' => 'index.php?s=test&c=home&m=index',

非常清晰的路由映射关系。



宸逸CMS控制器分为三种类型:前端控制器、用户控制器Member、后台控制器Admin、系统API路由(系统保留部分不允许开发)。

1、前端控制器:浏览者访问的动作,例如网站首页等

dayrui/App/Test/Controllers/Home.php

assign([
            'meta_title' => '测试页面',
        ]);
        \Phpcmf\Service::V()->display('test.html');// test.html后面视图部分会讲到
    }
}

访问地址:index.php?s=应用程序目录&c=控制器名称&m=方法名称


2、用户控制器:需要用户登录账号的操作,例如密码修改等

dayrui/App/Test/Controllers/Member/Home.php

assign([
            'meta_title' => '测试页面',
        ]);
        \Phpcmf\Service::V()->display('test.html');// test.html后面视图部分会讲到
    }
}

访问地址:index.php?s=member&app=应用程序目录&c=控制器名称&m=方法名称


3、后台控制器:管理员的操作

dayrui/App/Test/Controllers/Admin/Home.php

assign([
            'meta_title' => '测试页面',
        ]);
        \Phpcmf\Service::V()->display('test.html');// test.html后面视图部分会讲到
    }
}

访问地址:admin.php?s=应用程序目录&c=控制器名称&m=方法名称


4、系统API控制器(系统保留部分不允许开发,这里不做介绍)

dayrui/Fcms/Http/Controllers/Api/XXX.php

访问地址:index.php?s=api&c=XXX&m=方法名称


运用视图模板

\Phpcmf\Service::V()->assign([
    'test_var' => '这是一个变量',
]);
\Phpcmf\Service::V()->display('test.html');

上面代码是将变量赋值给模板输出,那么我们输出的模板是test.html

1、前端控制器模板文件

/template/pc或mobile/default/home/应用目录/test.html

2、用户控制器模板文件

/template/pc或mobile/default/member/应用目录/test.html

3、后台控制器模板文件

/dayrui/App/应用目录/Views/test.html

4、指定任意目录作为引用模板文件

\Phpcmf\Service::V()->set_dir('/www/www2/');
\Phpcmf\Service::V()->display('test.html'); //调用模板为:/www/www2/test.html


全局调用控制器

可以在自定义函数或者类中调用控制器中的方法和变量

\Phpcmf\Service::C(); 当前的控制器对象
\Phpcmf\Service::C()->member; 当前已经登录的用户信息,数组存储


数据模型数据操作

模型是专门用来和数据库打交道的 PHP 类。


创建模型类

dayrui/App/Test/Models/My.php

请注意文件和类名的命名格式:文件首字母必须大写,类名首字母必须大写。


模型类调用方式

\Phpcmf\Service::M('类文件名', 'APP目录名')->方法(参数)
例如:
\Phpcmf\Service::M('my', 'test')->my_test();


数据库对象用法

数据库对象调用方法

$this->db; // 这个写法只能在模型文件中写,
\Phpcmf\Service::M()->db; //这个可以任意地方写。


运行查询语句

$rt = $this->db->query("你的查询语句");


可参考手册:http://help.xunruicms.com/419.html



模型类数据操纵用法

一、组装方法

用于构造数据操作的条件方法,全部组装方法都返回数据对象,支持链式写法

1、设置数据表

$this->table("member") 解析为dr_member表

2、设置当前站点的数据表

$this->table_site("news", 1) 解析为dr_1_news表

3、设置where条件

$this->where("直接写条件");
$this->where("字段", "值");

4、设置where_in条件

$this->where_in("字段", "数组值");

5、设置排序条件(ASC,DESC)

$this->order_by("字段 值,字段 值");
$this->order_by('displayorder ASC,id DESC')

6、设置表自增主键,默认id

$this->id("字段", "值");


二、查询方法

1、查询全部数据

$this->组装方法->getAll($num, $key)
参数
介绍
$num默认为全部表,本次查询的数据量
$key默认为0,本次查询按哪个字段作为数值主键,主键由0开始;如果填写id,那么主键就是id

数据返回:多维数组类型

用法举例:

$this->table("member")->getAll(); // 全部会员数据
$this->table("member")->where("money>0")->getAll(); // 金额大于0的会员数据


2、按条件查询单个数据

$this->组装方法->getRow()

数据返回:一维数组类型

用法举例:

$this->table("member")->where("username", "admin")->getRow(); // 账号是admin的会员数据


3、按主键查询单个数据

$this->组装方法->get($id)

数据返回:一维数组类型

用法举例:

$this->table("member")->id('uid')->get(1); // uid=1的会员数据
$this->table_site("news")->get(1); // id=1的新闻主表内容


4、统计数据

$this->组装方法->counts("表名称")

数据返回:数字

用法举例:

\Phpcmf\Service::M()->where("catid", 1)->counts("1_news") 查询栏目id=1的新闻
\Phpcmf\Service::M()->counts("1_news") 全部新闻数据量


三、插入方法

$this->table("表名称")->id("主键字段")->insert(数据数组)
或者
$this->table("表名称")->id("主键字段")->replace(数据数组)
参数
介绍
表名称例如member
主键字段默认是id,就是表的自增字段
数据数组数组格式,例如: array("字段名称" => "值", ....)

数据返回:

$rt['code']:0失败;大于0,表示本条数据的主键值,自增值
$rt['msg']:失败原因

用法举例:

$rt = $this->table("test")->id("id")->insert([
    "title" => "标题字段",
    "content" => "内容字段",
]);
if($rt['code']) {
    // 成功
} else {
    // 失败
}


四、更新方法

$this->table("表名称")->id("主键字段")->update($id, 数据数组)
参数
介绍
表名称例如member
主键字段默认是id,就是表的自增字段
$id
主键字段的值
数据数组数组格式,例如: array("字段名称" => "值", ....)

数据返回:

$rt['code']:0失败;大于0,表示本条数据的主键值,自增值
$rt['msg']:失败原因

用法举例:

$rt = $this->table("test")->id("id")->update(1, [
    "title" => "标题字段",
    "content" => "内容字段",
]);
if($rt['code']) {
    // 成功
} else {
    // 失败
}


批量更新

$this->table("test")->update_batch([

[
"id" =>1,
    "title" => "标题字段",
    "content" => "内容字段",
],
[
"id" =>2,
    "title" => "标题字段22",
    "content" => "内容字段22",
]

], "id");
// 影响行数
$this->db->affectedRows();




五、删除方法

$this->table("表名称")->组装方法->id("主键字段")->delete($id)
参数
介绍
表名称例如member
主键字段可选, 默认是id,就是表的自增字段
$id
可选, 主键字段的值 可选

数据返回:

$rt['code']:0失败;大于0成功
$rt['msg']:失败原因

用法举例:

$rt = $this->table("test")->id("id")->delete(1); 删除id=1的记录
$rt = $this->table("test")->where("cid", 2)->delete(); 删除cid=2的记录


六、执行SQL方法

执行SQL语句

$rt = $this->query(SQL)

数据返回:

$rt['code']:1成功,0失败
$rt['msg']:失败原因

自定义函数

全局的自定义函数文件:dayrui/My/Helper.php

此文件用于放网站自定义函数,程序会自动加载


当前站点的自定义函数文件:网站主目录/config/custom.php


插件的自定义函数:https://www.xunruicms.com/doc/925.html




全局:IP库文件

cms采用纯真ip库(仅限开发者使用,不能用于商业),软件下载地址:

https://www.baidu.com/s?ie=UTF-8&wd=%E7%BA%AF%E7%9C%9Fip%E5%BA%93%E4%B8%8B%E8%BD%BD

ip库文件位置:

WRITEPATH.'qqwry.dat'
'/cache/qqwry.dat'

更新ip库文件方法:

blob.png

升级ip库之后将以下文件上传到cms的cache/之中:

blob.png


获取最新IP库,可以关于关注“传真IP实验室”公众号,获取最新的IP库,每周会不定时进行更新

系统目录常量介绍

常量目录说明默认目录描述
WEBPATH网站主目录/ 或者 /public入口文件index.php的目录
ROOTPATH网站主目录/ 或者 /public
同WEBPATH,多网站插件时表示主目录
FCPATH程序目录/dayrui/
APPSPATH插件和模块目录/dayrui/App/
CMSPATH框架主目录/dayrui/Fcms/
COREPATH框架主目录/dayrui/Fcms/
MYPATH程序引导目录/dayrui/My/
WRITEPATH缓存目录/cache/
CONFIGPATH公共配置文件目录/config/
TPLPATH
模板文件目录/template/


数据库操作

我们CMS内置了一个快速强大的数据库抽象类,支持传统的查询架构以及查询构造器模式。 数据库方法的语法简单明了。

同时支持Codeigniter、Laravel、ThinkPHP三种内核的数据库查询。


一、基本用法


数据库对象调用方法

\Phpcmf\Service::M()->db


运行查询语句

$rt = \Phpcmf\Service::M()->db->query("你的查询语句");



获取最后一次查询的sql语句

$query = \Phpcmf\Service::M()->db->getLastQuery();


二、查询结果


多个查询结果返回

$rt = \Phpcmf\Service::M()->db->query("select * from dr_member");
if ($rt) {
    $rows = $rt->getResultArray();
    foreach ($rows as $t) {
        echo $t['id'];
        .....
    }
}


单个查询结果返回

$rt = \Phpcmf\Service::M()->db->query("select * from dr_member where id=1");
if ($rt) {
    $row = $rt->getRowArray();
    echo $row['id'];
}


三、对象查询


统计某表数据

\Phpcmf\Service::M()->db->table('member')->countAllResults(); // 全部
\Phpcmf\Service::M()->db->table('member')->where('money', 0)->countAllResults(); // 带条件


条件查询表

$rt = \Phpcmf\Service::M()->db->table("member")->where("字段", "字段值")->get();
if ($rt) {
  $rows = $rt->getResultArray();
  var_dump($rows); 
}


限定数量查询

$rt = \Phpcmf\Service::M()->db->table("member")->limit(10, 0)->get();
if ($rt) {
  $rows = $rt->getResultArray();
  var_dump($rows); 
}


字段选择查询

$rt = \Phpcmf\Service::M()->db->table("member")->select("id,username,email")->get();
if ($rt) {
  $rows = $rt->getResultArray();
  var_dump($rows); 
}


四、插入数据

$data = array(
    'title' => 'My title',
    'name' => 'My Name',
    'date' => 'My date'
);
\Phpcmf\Service::M()->db->table('test')->insert($data);
echo $id = \Phpcmf\Service::M()->db->insertID(); // id

test是表名称,data数组是插入的字段和对应值


五、修改数据


按条件修改

$data = array(
    'title' => 'My title',
    'name' => 'My Name',
    'date' => 'My date'
);
\Phpcmf\Service::M()->db->table('test')->where('id', 123)->update($data);


字段分开写法

$db = \Phpcmf\Service::M()->db->table('mytable');
$db->where('id', 2);
$db->set('field', 'field + 1', false); 
$db->update();
//UPDATE mytable SET field = field+1 WHERE `id` = 2

$db = \Phpcmf\Service::M()->db->table('mytable');
$db->where('id', 2);
$db->set('field', 999);
$db->update();
//UPDATE mytable SET field = 999 WHERE `id` = 2


字段加减值

$db = \Phpcmf\Service::M()->db->table('mytable');
$db->where('id', 2);
$db->increment('field', 99);
//UPDATE mytable SET field = field+99 WHERE `id` = 2

$db = \Phpcmf\Service::M()->db->table('mytable');
$db->where('id', 2);
$db->decrement('field', 99);
//UPDATE mytable SET field = field-99 WHERE `id` = 2



六、数据删除


条件删除

$db = \Phpcmf\Service::M()->db->table('mytable');
$db->delete(array('id' => 123)); 
// DELETE FROM mytable  WHERE id = 123


清空表

$db = \Phpcmf\Service::M()->db->table('mytable');
$db->truncate();



七、事务处理


写法标准

\Phpcmf\Service::M()->trans_start(); // 开启事务
// 写入数据
\Phpcmf\Service::M()->table('member')->insert([
    'username' => '1',
    'phone' => 888,
    'salt' => 888,
    'name' => 888,
    'money' => 888,
    'freeze' => 888,
    'spend' => 888,
]);
\Phpcmf\Service::M()->trans_comment(); // 提交事务


回滚事务

\Phpcmf\Service::M()->trans_rollback(); 


八、其他


执行insert,update等时返回有多少行受影响

\Phpcmf\Service::M()->db->affectedRows();


全局:语言包配置

语言包文件介绍:

api/language/

此目录为语言文件目录,系统默认为zh-cn,表示中文,也是系统的主语言。


一、自定义网站语言

1、在语言目录下创建新语言,例如en

api/language/en/

然后把默认的zh-zn目录的语言文件复制进去。


2、在后台网站配置就可以看到en这个选项了

image.png


3、将js等文件全部翻译成英文吧


4、翻译替换php里面的中文,lang.php文件,格式如下:

 '新的语言',
 */

return [

    '保存' => 'Save',
    '修改' => 'Edit',

];

翻译过程比较繁琐,因为网站的所有文字都要写上去



二、变更语言内容

1、lang.php

当cms里面的文字不符合你的要求时你可以来修改他,修改lang.php文件,例如:

 '新的语言',
 */

return [
    // 把保持二字改成储存
    '保存' => '储存', 
    
    // 下面这句改验证码
    '您的本次验证码是: %s' => '你好,本次短信验证码是: %s,请不要告诉别人',

];


2、lang.js

// js语言包
var lang = new Array;
lang['ok'] = '确定';
lang['ts'] = '提示';
lang['ip'] = 'IP信息';
lang['esc'] = '取消';
lang['add'] = '添加';
lang['edit'] = '修改';
lang['code'] = '代码';
lang['show'] = '查看';
lang['send'] = '推送';
lang['save'] = '保存';
lang['copy'] = '复制';
lang['error'] = '系统错误';
lang['error_admin'] = '系统崩溃,请检查错误日志';
lang['member'] = '用户信息';
lang['paylog'] = '交易记录';
lang['todoing'] = '执行结果';
lang['logout'] = '你确定要退出吗?';
lang['htmlfile'] = '生成静态页';
lang['protocol'] = '用户注册协议';
lang['unloadtips'] = '数据未保存,你确定要离开吗?';
lang['unformid'] = '表单id属性不存在';
lang['repeatformid'] = '表单id属性已重复定义';
lang['确定'] = 'ok';
lang['取消'] = 'esc'; // 日期类型语言包 var finecms_datepicker_lang = { days: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"], daysShort: ["周日", "周一", "周二", "周三", "周四", "周五", "周六", "周日"], daysMin: ["日", "一", "二", "三", "四", "五", "六", "日"], months: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], monthsShort: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], today: "今日", clear: "清空", suffix: [], meridiem: [], titleFormat: "MM yyyy" }; /////////////////////////////////// lang['新的词语'] = '翻译后的词语';


3、如果用到过百度编辑器插件的,需要手动打开文件/api/ueditor/lang.js,把里面的内容复制到(2)中的js文件中,手动翻译他的内容


三、快速找到哪些文本需要翻译

1、开启开发者模式

index.php文件里面开启

全局:语言包配置

2、然后访问某一个页面,随便哪个页面都行

3、这时候系统会生成一个本页面需要翻译的文件内容,比如你的语言名称是en,那么生成的文件路径是

cache/lang_en.php,内容如下:

全局:语言包配置

这就代表当前页面有这些文字都要翻译

4、把这些文字复制到(二)的数组里面进行翻译

全局:语言包配置

5、然后将(3)文件的内容删除,依次重复(2、3、4)的步骤,直到所有语言被翻译完毕为止


四、前端模板文字写法

{dr_lang(中文)}

比如:

{dr_lang('产品')}

在英文语言包页面就会自动显示product


面包屑中当前模块名称

{dr_lang(MODULE_NAME)}


Table操作类

/Phpcmf/Table用于快速实现数据表的显示、增加、修改、删除等动作,适用于任何数据表的显示和操作。


一、示例说明

例如需要在增加一个资料表,用于录入资料数据,那么可以使用Table类快速实现数据的储存和显示。

image.png


1、下载Demo程序示例

Table类操作实例demo.zip

A、入门级别的Demo(推荐)

B、进阶级别的Demo



解压之后放到 dayrui/App目录之下,如下图所示

image.png


2、创建数据库,我们示例只做数据标题和数据内容的录入

CREATE TABLE `dr_test` (
  `id` int(11) NOT NULL,
  `title` varchar(255) NOT NULL,
  `content` text NOT NULL,
  `inputtime` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `dr_test`
  ADD PRIMARY KEY (`id`);
ALTER TABLE `dr_test`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;


3、界面预览,admin.php?s=test&c=test,即可看到以下界面:

image.png


这样就可以利用Table类进行增加、删除、修改操作,根本不需要开发者写多余的sql查询语句,Table类已经帮您处理好了。


二、解析Table类源码

1、构造函数初始化方法

public function __construct()
{
    parent::__construct();
    // 表单显示名称
    $this->name = dr_lang('资料数据');
    // 模板前缀(避免混淆)
    $this->tpl_prefix = 'test_';
    // 入库字段,实例中用到两个字段录入
    $field = array(
        'name' => array(
            'ismain' => 1,
            'name' => dr_lang('名称'),
            'fieldname' => 'name',
            'fieldtype' => 'Text',
            'setting' => array(
                'option' => array(
                    'width' => 200,
                ),
                'validate' => array(
                    'required' => 1,
                )
            )
        ),
        'content' => array(
            'ismain' => 1,
            'name' => dr_lang('资料内容'),
            'fieldtype' => 'Ueditor',
            'fieldname' => 'content',
            'setting' => array(
                'option' => array(
                    'mode' => 1,
                    'height' => 300,
                    'width' => '100%'
                ),
                'validate' => array(
                    'required' => 1,
                )
            )
        ),
    );
    // 初始化数据表
    $this->_init([
        'table' => 'test', // 表的名字
        'field' => $field, // 设置入库字段
        'show_field' => 'title', // 表的主字段
        'order_by' => 'id desc', // 列表排序显示方式
    ]);
    \Phpcmf\Service::V()->assign([
        'field' => $field,
        'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
        [
            $this->name => [APP_DIR.'/'.\Phpcmf\Service::L('Router')->class.'/index', 'fa fa-tag'],
            '添加' => [APP_DIR.'/'.\Phpcmf\Service::L('Router')->class.'/add', 'fa fa-plus'],
            '修改' => ['hide:'.APP_DIR.'/'.\Phpcmf\Service::L('Router')->class.'/edit', 'fa fa-edit'],
        ])
    ]);
}


关于初始化数据表的_init方法提供以下参数参考:

table           查询主表

field           可用搜索字段列表
date_field      列表搜索的时间字段,默认inputtime
show_field      显示主字段,用于修改日志
list_field      列表显示字段

order_by        默认排序方式
order_list      默认排序方式(同上一样)
group_by        分组参数
where_list      默认搜索条件,每次列表都执行
join_list       关联查询,格式:['member', 'member.id=admin.uid', 'left']
select_list     列表查询筛选字段


类的联动条件变量:

$this->edit_where = ''; 修改数据时候的条件判断
$this->delete_where = ''; 删除数据时候的条件判断
$this->list_where = ''; 数据列表时候的条件判断


2、数据列表方法

public function index() {
    list($tpl) = $this->_List(); // 完成table自动查询并分页显示动作
    \Phpcmf\Service::V()->display($tpl); // 设定显示模板
}


3、数据增加方法

public function add() {
    list($tpl) = $this->_Post(0); // 0表示新增post数据
    \Phpcmf\Service::V()->display($tpl);// 设定表单模板
}


4、数据修改方法

public function edit() {
    // 传入id到post方法表示修改此id提交的数据
    list($tpl) = $this->_Post(intval(\Phpcmf\Service::L('Input')->get('id')));
    \Phpcmf\Service::V()->display($tpl);
}


5、数据删除方法

public function del() {
    $this->_Del(
        \Phpcmf\Service::L('Input')->get_post_ids(), // 获取批量删除id号
        null, // 删除之前的函数验证
        null, // 删除之后的函数处理
        \Phpcmf\Service::M()->dbprefix($this->init['table']) // 设定删除表名称
    );
}


6、数据存储格式化方法

// 格式化保存数据
protected function _Format_Data($id, $data, $old) {
    if (!$id) {
      // 当提交新数据时,把当前时间插入进去
      $data[1]['inputtime'] = SYS_TIME;
    }
    return $data;
}


7、数据存储验证及判断

protected function _Save($id = 0, $data = [], $old = [], $func = null, $func2 = null) {
    return parent::_Save($id, $data, $old, function($id, $data, $old){
        // 保存之前执行的函数,并返回新的数据
        if (!$id) {
            // 当提交新数据时,把当前时间插入进去
            $data[1]['inputtime'] = SYS_TIME;
        }
        
        return dr_return_data(1, null, $data);
    }, function ($id, $data, $old) {
        // 保存之后执行的动作
    });
}

如果不写此方法的话就不会对数据进行格式化操作,按照提交表单原样储存


8、重新格式化编辑页面的字段输出格式

    protected function _Data($id = 0) {

        if (!$id) {
            return [];
        }

        $row = parent::_Data($id);
 
 //这里可以对数据进行格式化操作,例如,$row['value'] = dr_string2array($row['value']);

        return $row;
    }


数据缓存方法

数据缓存有效的减少重复查询数据库

一、临时缓存(按系统设置的缓存方式存储)

设置在有效时间内生效,过期自动删除,后台更新数据或者更新缓存时会被清空

缓存文件目录默认在/cache/file/,缓存文件命名格式为:字母或者数字组成

1、设置缓存

\Phpcmf\Service::L('cache')->set_data("缓存名称", "缓存变量值,支持数组", "缓存有效期,单位秒");

2、读取缓存

\Phpcmf\Service::L('cache')->get_data("缓存名称");

3、删除缓存

\Phpcmf\Service::L('cache')->del_data("缓存名称");
在有效时间内生效,过期自动删除,后台更新数据或者更新缓存时会被清空


二、固定缓存(按文件存储)

生成缓存之后,文件会固定存储,不会过期,后台更新数据或者更新缓存时不会被清空

缓存文件目录默认在/cache/data/,缓存文件由缓存名称命名

1、设置缓存

\Phpcmf\Service::L('cache')->set_file('缓存名称', "缓存变量值,支持数组", "指定储存文件夹,不填默认data");

2、读取缓存

\Phpcmf\Service::L('cache')->get("缓存名称"); // 不指定data时用这个
\Phpcmf\Service::L('cache')->get_file("缓存名称", "指定储存文件夹,不填默认data");

3、删除缓存

\Phpcmf\Service::L('cache')->del_file('缓存名称', "指定储存文件夹,不填默认data");


三、认证数据缓存(按文件存储)

生成缓存之后,文件会固定存储,默认情况下24小时过期,后台更新数据或者更新缓存时不会被清空

缓存文件目录默认在/cache/authcode/,缓存文件由缓存名称命名

1、设置缓存

\Phpcmf\Service::L('cache')->set_auth_data('缓存名称', "缓存变量值,支持数组", 站点id-默认可不填);

2、读取缓存

\Phpcmf\Service::L('cache')->get_auth_data("缓存名称", 站点id-默认可不填);

3、删除缓存

 \Phpcmf\Service::L('cache')->del_auth_data("缓存名称", 站点id-默认可不填);
默认情况下24小时过期,后台更新数据或者更新缓存时不会被清空

发布作品格式要求

一、插件类作品

插件机制可以实现对CMS的多元化开发

对CMS创建的模块机制进行改变、组装、重写
开发独立的项目程序应用
把扩展功能从框架中剥离出来,降低了框架的复杂度,让框架更容易实现
以一种很松的方式耦合,两者在保持接口不变的情况下,可以独立变化和发布
它能满足不同用户按需开发自己的功能

开发规范必须按照插件的格式,参考myapp的demo源码,也可以参考官方版的一些列插件


程序目录结构要求

安装程序必须满足以下目录布局

/WEBPATH/* 相对于网站主目录(会自动识别public目录)
/CSSPATH/* 相对于风格static目录
/APPSPATH/* 相对于插件dayrui/App目录
/TPLPATH/* 相对于模板目录,针对独立设计的模板,即使站长改变了默认模板名称,本目录也会自动识别
/FCPATH/* 相对于dayrui目录
/MYPATH/* 相对于dayrui/My/目录
/WRITEPATH/* 相对于cache缓存目录
/APPSPATH/* 相对于dayrui/App/目录
/CONFIGPATH/* 相对于config目录

/目录常量/* 将对于的文件归类到这些目录常量文件夹之中,即使是开发者修改了系统目录,当在线安装时程序也能识别对应的自定义目录


程序打包方法

将以上目录格式压缩成zip文件即可,一定要以当前目录为最高层次。


示例打包文件

Myapp.zip

开发上传插件必须按照此压缩包的文件格式来上传zip包。


插件目录命名规范:

/dayrui/App/插件目录
目录建议加上前缀字母,比如你的插件是news目录,那么你需要加几个前缀字母,以免跟其他插件重名,
例如你可以改成:CCnews、Snews、Anews等等


插件数据库表的命名规范:

数据表建议加上前缀字母,比如你的表叫dr_news,那么你需要加几个前缀字母,以免跟其他插件重名,
例如你可以改成:dr_cc_news、dr_aa_news、dr_xxx_news等等


自动执行安装插件的配置文件

/Install.php

内容格式:

 'app',
 'name' => '插件目录名称',
  
];


/Run.php 自动运行脚本,用于安装插件后的运行程序,比如创建数据表,创建数据等

内容格式:

当开发者配置完成后,在应用市场下载插件后,可以进行自动安装


/Check.php 安装前的检测工作,判断当前环境是否满足安装

内容格式:

_json(0, '当前环境无法安装本插件');



二、组件类作品

系统的某些功能、自定义字段、自定义方法或函数体等无规范性的程序。


程序目录结构要求

安装程序必须满足以下目录布局

/WEBPATH/* 相对于网站主目录
/CSSPATH/* 相对于风格static目录
/APPSPATH/* 相对于插件dayrui/App目录
/TPLPATH/* 相对于模板目录,针对独立设计的模板,即使站长改变了默认模板名称,本目录也会自动识别
/FCPATH/* 相对于dayrui目录
/MYPATH/* 相对于dayrui/My/目录
/WRITEPATH/* 相对于cache缓存目录
/APPSPATH/* 相对于dayrui/App/目录
....


/目录常量/* 将对于的文件归类到这些目录常量文件夹之中,目录常量参考文档


程序打包方法

将以上目录格式压缩成zip文件即可,一定要以当前目录为最高层次。

格式参考(一)中的插件打包示例格式。


三、模板类作品

需要附加安装方法和数据库文件

/WEBPATH/* 相对于网站主目录
/CSSPATH/* 相对于风格static目录
/APPSPATH/* 相对于插件dayrui/App目录
/TPLPATH/* 相对于模板目录,针对独立设计的模板,即使站长改变了默认模板名称,本目录也会自动识别
/FCPATH/* 相对于dayrui目录
/MYPATH/* 相对于dayrui/My/目录
/WRITEPATH/* 相对于cache缓存目录
/APPSPATH/* 相对于dayrui/App/目录
....


自动执行安装模板配置文件

/Install.php

内容格式:

 'tpl',
 'name' => '模板目录名称',
  
];


/Run.php 自动运行脚本,用于安装模板后的运行程序,比如创建数据表,创建数据等

内容格式:

prefix; // 表前缀
// \Phpcmf\Service::M()->query_all('数据更新sql语句');  // 数据前缀用通配符{dbprefix}

当开发者配置完成后,在应用市场下载模板后,可以进行自动安装:

image.png

/Check.php 安装前的检测工作,判断当前环境是否满足安装

内容格式:

_json(0, '当前环境无法安装本模板');


示例打包文件

模板示例结构.zip

开发上传模板必须按照此压缩包的文件格式来上传zip包。



后台调试器debug

后台开启调试器

image.png

调试器开启可以在后台看到sql等执行语句信息,有利于后台的调试;但是,前台不会受影响,前台需要开启开发者模式才会生效

调试器优势:

1、在后台直接搜索帮助文档

image.png

关闭调试模式后,会隐藏这部分


2、可以直接查看在线帮助手册

image.png

关闭调试模式后,会隐藏这部分


3、可以访问帮助手册入扣地址

image.png

关闭调试模式后,会隐藏这部分


4、可以查看页面执行情况

image.png

关闭调试模式后,会隐藏这部分


5、直观的显示错误信息

关闭调试模式后,遇到错误会显示500错误

数据获取POST和GET

1、$_GET写法

\Phpcmf\Service::L('input')->get('变量名'); // 会进行xss安全过滤
\Phpcmf\Service::L('input')->get('变量名', false); // 不会过滤


2、$_POST写法

\Phpcmf\Service::L('input')->post('变量名'); // 会进行xss安全过滤
\Phpcmf\Service::L('input')->post('变量名', false); // 不会过滤



浏览器缓存清理

清理浏览器缓存的方法

1、google浏览器

image

打开chrome浏览器,使用Ctrl+Shift+Delete快捷键,就会打开清理浏览数据页面,选择清理缓存选项, 然后单击“清除浏览数据”按键即可。

 或者单击浏览器上的扳手--选项--高级选项--隐私设置一栏中的清楚浏览数据 之后重复上面的步骤。


获取URI地址

前台和后台的URI路由地址:

APP目录/控制器文件/方法函数

会员中心的URI路由地址:

member/APP目录/控制器文件/方法函数


通过动态地址获取URL:

index.php?s=APP目录&c=控制器文件&m=方法函数


获取当前控制器的URI地址:

\Phpcmf\Service::L('Router')->uri();



相关例子:

1、网站首页的URI

{if \Phpcmf\Service::L('Router')->uri() == "home/index"}
    当前控制器是首页的
{/if}

2、news模块首页的uri

{if \Phpcmf\Service::L('Router')->uri() == "news/home/index"}
    当前控制器是news模块首页的
{/if}

3、news模块栏目的uri

{if \Phpcmf\Service::L('Router')->uri() == "news/category/index"}
    当前控制器是news模块栏目页的
{/if}

4、news模块内容的uri

{if \Phpcmf\Service::L('Router')->uri() == "news/show/index"}
    当前控制器是news模块内容目页的
{/if}

5、news模块搜索的uri

{if \Phpcmf\Service::L('Router')->uri() == "news/search/index"}
    当前控制器是news模快搜索页的
{/if}

6、会员中心首页的uri

{if \Phpcmf\Service::L('Router')->uri() == "member/home/index"}
    当前控制器是会员中心首页
{/if}

7、会员中心的news模块列表的uri

{if \Phpcmf\Service::L('Router')->uri() == "member/news/home/index"}
    当前控制器是会员中心news模块列表
{/if}


\Phpcmf\Service::类函数使用 / XR_函数

\Phpcmf\Service::类函数是xunruicms共用服务引用类,可在全局任意位置调用,定义文件是:dayrui/Fcms/Core/Service.php


注意:XR_开头的简化函数需要4.6以上版本才能使用。


1、控制器对象:\Phpcmf\Service::C()  或 XR_C()

用于读取当前url的控制器对象方法

例如调用控制器的uid参数,写法是:

\Phpcmf\Service::C()->uid


2、数据操作模型对象:\Phpcmf\Service::M() 或 XR_M()

用于进行数据库操作使用,增删改查操作

参考文档语法:http://help.xunruicms.com/207.html

数据库对象\Phpcmf\Service::M()->db可以简化为:XR_DB()


3、模板文件的对象:\Phpcmf\Service::V() 或 XR_V()

用户对页面模板的赋值和引用模板文件

参考语法:http://help.xunruicms.com/206.html


4、类库对象:\Phpcmf\Service::L() 或 XR_L()

用于调用系统类库和自定义类库的对象

自定义类库参考语法:http://help.xunruicms.com/925.html


5、函数库加载:\Phpcmf\Service::H() 或 XR_H()

用于加载自定义应用的自定义函数文件,加载了才能使用自定义函数文件。

https://www.xunruicms.com/doc/1153.html


6、读取文件内容:\Phpcmf\Service::R() 或 XR_R()

读取php文件的内容并返回

$rs = \Phpcmf\Service::R("/文件详细路径");


系统保留url参数变量

在开发者进行二次开发的时候,尽量避免使用系统保留url参数变量


c:控制器变量
s:项目变量
m:方法变量
app:应用目录变量
appid:api插件请求参数
uri:路由识别变量



如何通过url找控制器文件

CMS动态地址如下:

index.php?s=aa&c=bb&m=cc

s参数表示app目录(s参数留空表示核心程序Fcms/Control中的控制器文件)

c参数表示控制器文件名

m参数表示控制器文件中的方法函数名


一、APP插件或模块部分

APP目录文件可以自由修改

1、前端控制器URL结构

index.php?s=aaa&c=bbb&m=ccc

对应的控制器文件是:/dayrui/App/Aaa/Controllers/Bbb.php


2、前端会员控制器URL结构

index.php?s=member&app=aaa&c=bbb&m=ccc

对应的控制器文件是:/dayrui/App/Aaa/Controllers/Member/Bbb.php


3、后台控制器URL结构

admin.php?s=aaa&c=bbb&m=ccc

对应的控制器文件是:/dayrui/App/Aaa/Controllers/Admin/Bbb.php



二、核心CMS程序部分

核心程序部分是不能二次修改,不能修改他的文件内容

1、前端控制器URL结构

index.php?c=aaa&m=bbb

对应的控制器文件是:/dayrui/Fcms/Control/Aaa.php (此文件不能二次修改


2、后台控制器URL结构

admin.php?c=aaa&m=bbb

对应的控制器文件是:/dayrui/Fcms/Control/Admin/Aaa.php (此文件不能二次修改


3、api控制器url结构

index.php?s=api&c=aaa&m=bbb

对应的控制器文件是:/dayrui/Fcms/Control/Api/Aaa.php (此文件不能二次修改


通过开发者工具来找对应的控制器文件方法

1、打开开发者工具开,位于index.php,手册有开启方法

2、打开页面底部小火苗图标,切换到路由选项

如何通过url找控制器文件


日志记录函数

1、系统日志中的函数语法:

log_message('error', '这里输入错误日志内容')
log_message('debug', '这里输入调试日志内容')


写入日志成功后,可以在系统错误日志里面看到记录。

{xunruicms_img_title}


2、后台操作日志

\Phpcmf\Service::L('input')->system_log("日志内容,后台没有开启操作日志时不会插入");
\Phpcmf\Service::L('input')->system_log("日志内容,强制插入",true);

日志记录函数

生成自定义字段类别代码

使用Table类的控制器中如何自定义字段类别

1、在开发者插件中,点 生成字段代码 

image

2、填写字段名称和一些列的参数

image

3、将二次开发时的配置数组代码,复制起来

image

4、来到对应的Table控制器中,找到此字段的配置数组,如下图

image

5、替换新的代码(3)中复制的代码,如下图:

image


6、然后发布控制器即可看到此字段的效果:

image

创建数据控制器

数据控制器应用比较广泛,可以对数据表进行增删改查操作,利用开发者工具实现傻瓜式创建,非常方便

例如数据表:

CREATE TABLE IF NOT EXISTS `{dbprefix}my_test` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `uid` mediumint(8) unsigned DEFAULT NULL COMMENT '会员',
  `title` varchar(150) NOT NULL COMMENT '标题',
  `neirong` text NOT NULL COMMENT '内容',
  `inputtime` int(10) unsigned NOT NULL COMMENT '录入时间',
  PRIMARY KEY (`id`),
  KEY `uid` (`uid`),
  KEY `inputtime` (`inputtime`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='测试表';


1、创建以上数据表

{xunruicms_img_title}

2、使用开发者插件,去任意app目录创建数据控制器

{xunruicms_img_title}


3、创建后台的数据控制器

{xunruicms_img_title}


4、取名,选择数据库,选择模板

{xunruicms_img_title}

新手可以选择共享模板,傻瓜式配置


5、创建成功,点击查看

{xunruicms_img_title}


6、查看创建路径和访问地址

{xunruicms_img_title}


7、这时候手动访问主控制器

/admin.php?s=demo&c=my&m=index

{xunruicms_img_title}


8、点击添加按钮,可预览

{xunruicms_img_title}

默认都是文本格式,我们需要改成自定义字段模式

会员:做成录入账号

标题:可以用文本格式

内容:改为编辑器

录入时间:改为日期选择


9、打开控制器文件:/dayrui/App/Demo/Controllers/Admin/My.php

然后使用开发者工具来生成字段,看视频操作:

最终代码:

       $field = array (
  'uid' => 
  array (
    'name' => '会员',
    'fieldname' => 'uid',
    'ismain' => 1,
    'ismember' => 1,
    'fieldtype' => 'Uid',
  'setting' => 
  array (
    'option' => 
    array (
      'width' => '',
      'icon' => '',
      'name' => '',
      'color' => '',
      'func' => '',
      'css' => '',
    ),
    'validate' => 
    array (
      'required' => '0',
      'pattern' => '',
      'errortips' => '',
      'check' => '',
      'filter' => '',
      'formattr' => '',
      'tips' => '',
    ),
  ),
  'ismember' => '1',
  ),
  'title' => 
  array (
    'name' => '标题',
    'fieldname' => 'title',
    'ismain' => 1,
    'ismember' => 1,
    'fieldtype' => 'Text',
  ),
  'neirong' => 
  array (
    'name' => '内容',
    'fieldname' => 'neirong',
    'ismain' => 1,
    'ismember' => 1,  'fieldtype' => 'Ueditor',
  'setting' => 
  array (
    'option' => 
    array (
      'down_img' => '0',
      'autofloat' => '0',
      'remove_style' => '0',
      'div2p' => '0',
      'autoheight' => '0',
      'page' => '0',
      'mode' => '1',
      'tool' => '\'bold\', \'italic\', \'underline\'',
      'mode2' => '1',
      'tool2' => '\'bold\', \'italic\', \'underline\'',
      'mode3' => '1',
      'tool3' => '\'bold\', \'italic\', \'underline\'',
      'simpleupload' => '0',
      'attachment' => '0',
      'image_reduce' => '',
      'image_endstr' => '',
      'value' => '',
      'width' => '100%',
      'height' => '300',
      'css' => '',
    ),
    'validate' => 
    array (
      'required' => '0',
      'pattern' => '',
      'errortips' => '',
      'check' => '',
      'filter' => '',
      'formattr' => '',
      'tips' => '',
    ),
  ),
  'ismember' => '1',
  ),
  'inputtime' => 
  array (
    'name' => '录入时间',
    'fieldname' => 'inputtime',
    'ismain' => 1,
    'ismember' => 1,  'fieldtype' => 'Date',
  'setting' => 
  array (
    'option' => 
    array (
      'format2' => '0',
      'is_left' => '0',
      'value' => '',
      'width' => '',
      'color' => '',
      'css' => '',
    ),
    'validate' => 
    array (
      'required' => '0',
      'pattern' => '',
      'errortips' => '',
      'check' => '',
      'filter' => '',
      'formattr' => '',
      'tips' => '',
    ),
  ),
  ),
);



10、为列表页面设置显示字段

{xunruicms_img_title}

打开控制器文件:/dayrui/App/Demo/Controllers/Admin/My.php,,找到列表配置字段部分:

{xunruicms_img_title}

此配置格式为:

     array (
                    'use' => '1', // 1是显示,0是不显示
                    'name' => '', //显示名称
                    'width' => '', // 显示宽度
                    'func' => '', // 回调函数见:http://help.xunruicms.com/463.html
                    'center' => '0', // 1是居中,0是默认
                )

于是,修改后的代码为:

        $list_field = array (
  'uid' => 
  array (
    'use' => '1',
    'name' => '会员',
    'width' => '150',
    'func' => 'uid',
    'center' => '0',
  ),
  'title' => 
  array (
    'use' => '1',
    'name' => '标题',
    'width' => '',
    'func' => 'title',
    'center' => '0',
  ),
  'inputtime' => 
  array (
    'use' => '1',
    'name' => '录入时间',
    'width' => '170',
    'func' => 'datetime',
    'center' => '0',
  ),
);

内容不显示在列表了


11、预览效果如下:

{xunruicms_img_title}



傻瓜式创建的数据控制器非常方便的进行数据个性化管理,用途非常大

应用插件的函数库文件

基于App目录下的插件或模块如何创建自己的函数库呢

1、新建文件:dayrui/App/Test/Helpers/My.php (文件名首字母大写)

2、新写方法体:

加载函数文件,相当于是require操作:

\Phpcmf\Service::H('文件名称', 'app目录名称');

那么,加载后才能使用自定义函数:

\Phpcmf\Service::H('my', 'test');
echo my_test_hello();


调试变量记录/打印变量

使用本功能需要安装:开发者工具插件。

{xunruicms_img_title}


函数语法:

dr_debug('文件名称', $传入变量)


函数作用:

用于二次开发时候的调试打印变量,相当于file_put_contents("aa.txt", var_export($data, true)),会开发经验的一般看得懂这句话都一样。


用法举例:

在控制器中写入记录函数:

dr_debug('test', $this->member); // 打印输出变量

访问控制器触发,可以在开发者工具中查看记录(如上图位置)

{xunruicms_img_title}

可以一目了然的看出变量信息。




系统自定义js文件my.js

/static/assets/js/my.js

此文件会被系统后台主动加载,前端需要开发者自己手动去加载它

用途:

存储一些自定义的js函数,或引入js库等功能

读取配置缓存get_cache

读取配置缓存函数格式:

\Phpcmf\Service::C()->get_cache("缓存字符串");


读取模块配置缓存:

\Phpcmf\Service::C()->get_cache("module-站点ID-模块目录");



dr_url与dr_member_url函数

dr_url :生成后台和前台的URL地址

dr_member_url:生成用户中心前台的URL地址


参数一:URI地址段(APP目录/控制器文件/方法函数)

参数二:其他数组参数


例如:dr_url("news/home/index")

前端调用表示 index.php?s=news&c=home&m=index 

后端调用表示 admin*.php?s=news&c=home&m=index 


例如:dr_member_url("news/home/index")

前端调用表示 index.php?s=member&app=news&c=home&m=index 

后端调用使用 dr_url函数


带参数的写法:dr_url("news/home/index", ["p1" => 1, 'p2' => 2])

前端调用表示 index.php?s=news&c=home&m=index&p1=1&p2=2 

后端调用表示 admin*.php?s=news&c=home&m=index&p1=1&p2=2

 

后台内页顶部导航菜单

内页顶部导航菜单,如下图所示位置:

后台内页顶部导航菜单


在控制器中的定义方式:
\Phpcmf\Service::V()->assign([
 'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
  [
   '菜单名称' => ['app目录/控制器名/方法名', 'fa fa-folder icon图标'],
   '菜单名称2' => ['app目录/控制器名/方法名', 'fa fa-folder icon图标'], // 支持多组菜单
  ]
 ),
]);


附带参数的地址:
\Phpcmf\Service::V()->assign([
 'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
  [
   '菜单名称' => ['test/test/index{参数1=值1&参数2=值2}', 'fa fa-folder'],
  ]
 ),
]);


弹出窗口储存地址:

后台内页顶部导航菜单

\Phpcmf\Service::V()->assign([
 'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
  [
   '菜单名称' => ['add:test/test/index', 'fa fa-folder', '500px', '400px'], // 500和400是高宽度
  ]
 ),
]);


跳转新页面方式:
\Phpcmf\Service::V()->assign([
 'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
  [
   '菜单名称' => ['blank:test/test/index', 'fa fa-folder'], // 在浏览器新标签打开
  ]
 ),
]);


ajax请求结果地址:

后台内页顶部导航菜单

\Phpcmf\Service::V()->assign([
 'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
  [
   '菜单名称' => ['ajax:test/test/index', 'fa fa-folder'], // 访问时会发起ajax请求,并提示结果
  ]
 ),
]);


帮助链接地址:
\Phpcmf\Service::V()->assign([
 'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
  [
   'help' => [888], // 888跳转到官网手册的地址 help.xunruicms.com/888.html
  ]
 ),
]);




系统函数/内置函数

宸逸cms内置的函数,位于文件:dayrui/Fcms/Core/Helper.php(此文件请不要修改)


判断是否为空白
dr_is_empty($value)
参数1$value
返回值是否空白

是否301跳转
dr_is_sys_301()
返回值是否301跳转

两个变量判断是否有值并返回
dr_else_value($a, $b)
参数1$a 变量1
参数2$b 变量2
返回值$a 有值时返回$a 否则返回$b

安全url过滤
dr_safe_url($url, $is_html = false)
参数1$url URL地址
参数2$is_html 是否作为html转换
返回值过滤后的URL地址

模糊比较两个变量
dr_diff($str1, $str2)
参数1$str1 变量1
参数2$str2 变量2
返回值判断两个变量是否相等

返回包含数组中所有键名的一个新数组
dr_array_keys($array, $value = '', $strict = false)
参数1$array 指定数组
参数2$value 具体值
参数3$strict 严格比较
返回值返回包含数组中所有键名的一个新数组

返回包含数组中指定键名的对应值
dr_array_value($array, $key)
参数1$array 指定数组
参数2$key 数组key
返回值返回包含数组中指定键名的对应值

判断存在于数组中
dr_in_array($var, $array)
参数1$var|array 指定值或数组
参数2$array 指定数组
返回值判断$var是否存在于数组$array中

两个数组比较
dr_array_intersect($arr1, $arr2)
参数1$arr1 指定数组1
参数2$arr2 指定数组2
返回值比较两个数组的键值,并返回交集

两个数组比较
dr_array_intersect_key($arr1, $arr2)
参数1$arr1 指定数组1
参数2$arr2 指定数组2
返回值比较两个数组的键名,并返回交集

字符长度
dr_strlen($string)
参数1$string 字符串
返回值返回字符串的长度

字符是否包含
dr_strpos($string, $key)
参数1$string 原字符串
参数2$key 查询的字符串
返回值返回$string中是否包含$key,区分大小写

字符是否包含
dr_stripos($string, $key)
参数1$string 原字符串
参数2$key 查询的字符串
返回值返回$string中是否包含$key,不区分大小写

上传移动文件
dr_move_uploaded_file($tempfile, $fullname)
参数1$tempfile 临时文件
参数2$fullname 存储文件
返回值将临时文件存储到指定的目录中

html实体字符转换
dr_html2code($value)
参数1$value 指定字符串
参数2$fullname 存储文件
返回值用htmlspecialchars进行html转码值

html实体字符转换
dr_code2html($value, $fk = false, $flags = '')
参数1$value 指定字符串
参数2$fk 强制转为utf8
参数3$flags 用下列标记中的一个或多个作为一个位掩码
返回值htmlspecialchars_decode进行html转码值

html实体字符转换
dr_html_code($value, $fk = false, $flags = '')
参数1$value 指定字符串
参数2$fk 强制转为utf8
参数3$flags 用下列标记中的一个或多个作为一个位掩码
返回值htmlspecialchars_decode进行html转码值

快捷登录接入商信息列表
dr_oauth_list()
返回值返回文件数组

判断是否是移动端终端if (!function_exists('dr_is_mobile')) {
dr_is_mobile()
返回值bool

后台搜索字段过滤函数
dr_is_admin_search_field($t)
参数1$t 单个字段数组
返回值是否被搜索时可用

通过数组值查找数组key
dr_get_array_key($array, $value)
参数1$array 数组
参数2$value 指定键值
返回值返回键值对应的键名

站点信息/项目信息的字段输出(自定义模板方式)
dr_site_info($name, $siteid = SITE_ID)
参数1$name 字段名
参数2$siteid 项目/站点id
返回值字段值

站点信息/项目信息的字段输出(自定义字段方式)
dr_site_value($name, $siteid = SITE_ID)
参数1$name 字段名
参数2$siteid 项目/站点id
返回值字段值

ftable字段输出
dr_get_ftable($id, $value, $class = '')
参数1$id 字段id
参数2$value 存储值
参数3$class 给table指定class
返回值表格

ftable字段数组
dr_get_ftable_array($id, $value)
参数1$id 字段id
参数2$value 存储值
返回值表格输出

获取内容中的缩略图
dr_get_content_img($value, $num = 0)
参数1$value 内容值
参数2$num 指定获取数量
返回值在变量中提取img标签的图片路径到数组

获取内容中的指定标签URL地址
dr_get_content_url($value, $attr, $ext, $num = 0)
参数1$value 内容值
参数2$attr 标签值,例如src
参数3$ext 指定扩展名,例如jpg|gif
参数4$num 指定获取数量
返回值在变量中提取img标签的图片路径到数组

插件是否被安装
dr_is_app($dir)
参数1$dir 插件英文名
返回值bool

模块是否被安装
dr_is_module($dir, $siteid = SITE_ID)
参数1$dir 模块英文名
参数2$siteid 站点id
返回值bool

字符串替换函数
dr_rp($str, $o, $t)
参数1$str 指定字符串
参数2$o 需要替换的值
参数3$t 替换后的值
返回值进行str_replace运算

替换模板参数特殊字符
dr_rp_view($str, $rt = 0)
参数1$str 指定字符串
参数2$rt 正向或者反向
返回值特殊字符替换

二维码调用
dr_qrcode($text, $thumb = '', $level = 'H', $size = 5)
参数1$text 指定字符串
参数2$thumb 中间图片
参数3$level 等级字母
参数4$size 大小值
返回值生成二维码图片url

秒转化时间
dr_sec2time($times)
参数1$times 多少秒
返回值返回秒对于的时分秒值

格式化多文件数组
dr_get_files($value, $limit = '')
参数1$value json字符
参数2$limit 限定返回几个值
返回值格式化多文件数组

格式化图片专用数组
dr_get_image($value)
参数1$value json字符
返回值格式化图片专用数组

文件上传临时目录
dr_upload_temp_path()
返回值文件上传临时目录

星级显示
dr_star_level($num, $shifen = 0)
参数1$num 数字
参数2$shifen 按十分计算
返回值星级显示

格式化sql创建
dr_format_create_sql($sql)
参数1$sql
返回值格式化sql创建

获取cms域名部分
dr_cms_domain_name($url)
参数1$url 指定url
返回值从指定url中获取cms域名部分

多语言输出
dr_lang(...$param)
参数1$param 指定文字
返回值将指定文字转换成系统对于的语言文字

获取终端列表
dr_client_data()
返回值获取终端列表

格式化编辑器内容数据
dr_ueditor_html($value, $title = '')
参数1$value 指定文字
参数2$title title标题值
返回值将UEDITOR_IMG_TITLE替换成指定的标题

获取域名部分
dr_get_domain_name($url)
参数1$url
返回值从$url中获取到域名

按百分比分割数组
dr_save_bfb_data($data, $num = 100)
参数1$data 数组
参数2$num 分成几等分
返回值将数组按百分比等分划分

会员头像存储目录
dr_avatar_dir($uid)
参数1$uid
返回值按uid进行分配头像存储目录

会员头像存储路径
dr_avatar_path()
返回值返回头像存储目录和对于的访问url

会员头像if (!function_exists('dr_avatar')) {
dr_avatar($uid, $fix = 1)
参数1$uid
参数2$fix 是否加时间戳后缀
返回值会员头像url

调用会员详细信息(自定义字段需要手动格式化)
dr_member_info($uid, $name = '', $cache = -1)
参数1$uid 会员uid
参数2$name 输出字段
参数3$cache 缓存时间
返回值用户详情数组

调用会员详细信息(自定义字段需要手动格式化)
dr_member_username_info($username, $name = '', $cache = -1)
参数1$username 会员账号
参数2$name 输出字段
参数3$cache 缓存时间
返回值用户详情数组

执行函数
dr_list_function($func, $value, $param = [], $data = [], $field = [], $name = '')

联动菜单包屑导航
dr_linkagepos($code, $id, $symbol = ' > ', $url = '', $html = '')
参数1string $code 联动菜单代码
参数2intval $id id
参数3string $symbol 间隔符号
参数4string $url url地址格式,必须存在[linkage],否则返回不带url的字符串
参数5string $html 格式替换
返回值string

联动菜单调用
dr_linkage($code, $id, $level = 0, $name = '')
参数1string $code 菜单代码
参数2intval $id 菜单id
参数3intval $level 调用级别,1表示顶级,2表示第二级,等等
参数4string $name 菜单名称,如果有显示它的值,否则返回数组
返回值array

联动菜单json数据
dr_linkage_json($code)
参数1string $code 菜单代码
参数2intval $pid 菜单父级id或者别名
返回值array

联动菜单列表数据
dr_linkage_list($code, $pid)
参数1string $code 菜单代码
参数2intval $pid 菜单父级id或者别名
返回值array

联动菜单的id号获取
dr_linkage_id($code, $cname)
参数1string $code 菜单代码
参数2string $cname 别名
返回值array

联动菜单的别名获取
dr_linkage_cname($code, $id)
参数1string $code 菜单代码
参数2int $id id
返回值array

联动菜单的最大层级
dr_linkage_level($code)
参数1string $code 菜单代码
返回值array

支付表单调用mark 表名-主键id-字段idvalue 支付金额title 支付说明
dr_payform($mark, $value = 0, $title = '', $url = '',  $remove_div  = 1)

字段表单调用field 字段配置value 默认值remove_div 移除div区域load_js 重新加载js文件
dr_fieldform($field, $value = '', $remove_div  = 1, $load_js = 0)

资料块内容
dr_block($id, $type = 0, $site = 0)
参数1intval $id
返回值array

全局变量调用
dr_var_value($name)
参数1string $name 别名
返回值

文件真实地址
dr_get_file($id, $full = 0)

文件下载地址
dr_down_file($id, $name = '')

根据附件信息获取文件地址
dr_get_file_url($data, $w = 0, $h = 0)
参数1array $data
返回值string

任意字段的选项值(用于options参数的字段,如复选框、下拉选择框、单选按钮)
dr_field_options($id)
参数1intval $id
返回值array

验证用户权限(废弃)my 我的authidauth 目标权限组return 1有权限 0无权限
dr_member_auth($my, $auth)

用于用户权限取取反值(废弃)
dr_member_auth_id($authid, $postid)

获取折扣价格值
dr_zhe_price($value, $zhe)
参数1$value 价格值
参数2$zhe 折扣值
返回值折扣计算后的值

获取价格值
dr_price_value($value, $num = 2)
参数1$value 价格值
参数2$num 小数位
返回值计算后的值

sku 获取属性值名称
dr_sku_value_name($value, $sku, $name)
参数1$value 字段值
参数2$sku sku数组
参数3$name 属性key
返回值属性名称

sku 价格信息
dr_sku_price($value, $number = 2, $join = ' - ', $zhe = 0)
参数1$value 字段值
参数2$number 小数位
参数3$join 连接符号
参数4$zhe 折扣值
返回值最终计算值

sku 获取名称
dr_sku_name($key, $data, $type = 0)
参数1$key sku字符串
参数2$data 主题数组
参数3$type 默认
返回值属性名称

下一个升级值
dr_level_next_value($array, $id)
参数1$array 用户组数组
参数2$id 组id号
返回值下一个升级值

静态生成时权限认证字符(加密)
dr_html_auth($ip = 0)
参数1$ip 运行者ip地址
返回值返回逻辑值

付款方式显示
dr_pay_type_html($name)
参数1$name 支付名
返回值返回数组

付款方式显示
dr_pay_name($name)
参数1$name 支付名
返回值返回数组

付款方式的名称
dr_pay_type($name)
参数1$name 支付名
返回值返回数组

付款状态的名称
dr_pay_status($data)
参数1$data 支付记录数据
返回值返回状态

付款金额显示
dr_pay_money_html($data, $v = 2)
参数1$data 价格值
参数2$v 小数位
返回值返回带html的金额值标签

清除空白字符
dr_clear_empty($value)
参数1$value 字符串
返回值返回字符串

列表字段进行排序筛选
dr_list_field_order($field)
参数1$field 字段列表数组
返回值返回过滤后的数组

两数组追加合并
dr_array2array($a1, $a2)
参数1$a1 数组1
参数2$a2 数组2
返回值返回合并后的数组

两数组覆盖合并
dr_array22array($a1, $a2)
参数1$a1 1是老数据
参数2$a2 2是新数据
返回值返回处理后的数组

判断是否启用了内容系统插件
dr_is_use_module()

站点表前缀
dr_site_table_prefix($table, $siteid = SITE_ID)
参数1$table 表名
参数2$siteid 站点id
返回值返回当前站点对应的表名称

模块表前缀
dr_module_table_prefix($dir, $siteid = SITE_ID)
参数1$dir 模块目录
参数2$siteid 站点id
返回值返回当前站点对应的表名称

模块表单前缀
dr_mform_table_prefix($dir, $table, $siteid = SITE_ID)
参数1$dir 模块目录
参数2$table 表名
参数3$siteid 站点id
返回值返回当前站点对应的表名称

网站表单表前缀
dr_form_table_prefix($dir, $siteid = SITE_ID)
参数1$dir 表单名
参数2$siteid 站点id
返回值返回当前站点对应的表名称

返回图标
dr_icon($value)
参数1$value 原定的图标
返回值如没有原地图标就返回默认图标

完整的文件URL
dr_file($url, $full = 0)
参数1$url 文件参数
参数2$full 是否补全绝对域名
返回值返回文件的完整url地址

根据文件扩展名获取文件预览信息
dr_file_preview_html($value, $id = 0)
参数1$value 文件路径参数
参数2$id 文件id值
返回值返回文件可预览的img标签

文件是否是图片@param $value 文件路径参数@return 判断这个是否是一张图片
dr_is_image($value)

格式化复选框\单选框\选项值
dr_format_option_array($value)
参数1$value 参数
返回值字符串转换为数组

字段输出表单(废弃)
dr_field_input($name, $type, $option, $value = '', $id = 0)

目录列表获取
dr_dir_map($source_dir, $directory_depth = 0, $hidden = FALSE)
参数1$source_dir 源目录
参数2$directory_depth 目录纵深 0全目录 1当前目录
参数3$hidden 是否包含隐藏目录
返回值整个目录名的数组格式

文件列表获取
dr_file_map($source_dir)
参数1$source_dir 源目录
参数2$directory_depth 目录纵深 0全目录 1当前目录
参数3$hidden 是否包含隐藏目录
返回值整个文件名的数组格式

数据返回统一格式
dr_return_data($code, $msg = '', $data = [], $extend = [])
参数1$code 状态码 0失败 >1表示成功
参数2$msg 提示文字
参数3$data 传输数组
参数4$extend 根附加数组
返回值返回统一的数组格式

提交表单默认隐藏域
dr_form_hidden($data = [])
参数1$data 可填充的隐藏域数组格式
返回值表单隐藏域控件代码

验证csrf字符串
dr_get_csrf_token()

搜索表单隐藏域
dr_form_search_hidden($p = [])
参数1$p 可填充的隐藏域数组格式
返回值表单隐藏域控件代码

Base64加密
dr_base64_encode($string)
参数1$string 参数
返回值加密后的字符串

Base64解密
dr_base64_decode($string)
参数1$string 参数
返回值解密后的值

网站风格目录
dr_get_theme()
返回值网站风格目录数组

获取6位数字随机验证码
dr_randcode()

删除目录及目录下面的所有文件
dr_dir_delete($path, $del_dir = FALSE, $htdocs = FALSE, $_level = 0)
参数1$dir 路径
参数2$is_all 包括删除当前目录
返回值如果成功则返回 TRUE,失败则返回 FALSE

基于本地存储的加解密算法
dr_authcode($string, $operation = 'DECODE')
参数1$string 传入字符串
参数2$operation DECODE是解密,否则是加密
返回值返回加解密后的值

当前浏览器的URL
dr_now_url()

验证码图片获取
dr_code($width, $height, $url = '')
参数1$width 宽度
参数2$height 高度
参数3$url 废弃
返回值返回验证码img标签的格式

排序字符串转换操作
dr_sorting($name)
参数1$name 字段名称
返回值根据浏览器order参数返回对应的字符串

移除order字符串
dr_member_order($url)
参数1$url 指定url地址
返回值把url中的order参数移除

用户等级 显示星星
dr_show_stars($num, $starthreshold = 4)
参数1$num
参数2$starthreshold 星星数在达到此阈值(设为 N)时,N 个星星显示为 1 个月亮、N 个月亮显示为 1 个太阳。
返回值img标签值

动态调用模板
dr_ajax_template($id, $filename, $param_str = '')
参数1$id div控件的ID名
参数2$filename 模板文件名
参数3$param_str 附加URL参数
返回值返回ajax调用代码

https进行post数据
dr_post_json_data($url, $param = [])
参数1$url 请求地址
参数2$param 请求参数数组
返回值返回信息

调用远程数据 curl获取
dr_catcher_data($url, $timeout = 0, $is_log = true, $ct = 0)
参数1$url
参数2$timeout 超时时间,0不超时
参数3$is_log 0表示请求失败不记录到系统日志中
参数4$ct 0表示不尝试重试,1表示重试一次
返回值请求结果值

伪静态代码处理
dr_search_rewrite_encode($params, $search)
参数1$params 参数数组
参数2$search 搜索配置
返回值string

伪静态代码转换为数组
dr_search_rewrite_decode($params, $search)
参数1$params 参数字符串
返回值参数数组

伪静态代码处理
dr_rewrite_encode($params, $join = '-', $field = [])
参数1$params 参数数组
返回值组合后的字符串

伪静态代码转换为数组
dr_rewrite_decode($params, $join = '-', $field = [])
参数1$params 参数字符串
返回值数组参数

安全过滤格式化搜索关键词参数
dr_get_keyword($s)
参数1$s 参数
返回值处理后的值

安全过滤格式化搜索关键词参数@param $s 参数@return 处理后的值
dr_safe_keyword($s)

安全过滤函数
dr_safe_replace($string, $diy = [])
参数1$string 参数
参数2$diy 自定义过滤数组配置
返回值处理后的值

安全过滤文件及目录名称函数
dr_safe_filename($string)
参数1$string 参数
返回值处理后的值

安全过滤用户名函数
dr_safe_username($string)
参数1$string 参数
返回值处理后的值

安全过滤密码函数
dr_safe_password($string)
参数1$string 参数
返回值处理后的值

后台移除http和https协议
dr_rm_http($url)
参数1$url 地址
返回值处理后的值

将路径进行安全转换变量模式
dr_safe_replace_path($path)
参数1$path 目录名
返回值处理后的值

字符截取
dr_strcut($string, $limit = '100', $dot = '...')
参数1$string 字符串
参数2$limit 长度限制
参数3$dot 超出的填充字符串
返回值处理后的值

单词截取
dr_wordcut($text, $maxchar, $end = '...')
参数1$string 字符串
参数2$maxchar 长度限制
参数3$end 超出的填充字符串
返回值处理后的值

随机颜色
dr_random_color()
返回值随机后的颜色值

友好时间显示函数
dr_fdate($sTime, $formt = 'Y-m-d')
参数1$time 时间戳
参数2$formt 时间太长时的格式输出
返回值string

时间显示函数
dr_date($time = '', $format = SITE_TIME_FORMAT, $color = '')
参数1$time 时间戳
参数2$format 格式与date函数一致
参数3$color 当天显示颜色
返回值string

将对象转换为数组
dr_object2array($obj)
参数1$obj 数组对象
返回值array

数组截取
dr_arraycut($arr, $limit)
参数1$arr 数组值
参数2$limit 长度限制
返回值处理后的数组

将字符串转换为数组
dr_string2array($data, $limit = '')
参数1$data 字符串
返回值array

将数组转换为字符串
dr_array2string($data)
参数1$data 数组
返回值string

递归创建目录
dr_mkdirs($dir, $null = true)
参数1$dir 目录名称
返回值bool|void

格式化输出文件大小
dr_format_file_size($fileSize, $round = 2)
参数1$fileSize 大小
参数2$round 保留小数位
返回值string

关键字高亮显示
dr_keyword_highlight($string, $keyword, $rule = '')
参数1$string 字符串
参数2$keyword 关键字,可数组
返回值string

正则替换和过滤内容
dr_preg_html($html)
参数1$html
返回值过滤后的字符串

格式化微博内容中url内容的长度(废弃)
_format_feed_content_url_length($match)

二维码地址生成
dr_qrcode_url($text, $uid = 0, $level = 'L', $size = 5)
参数1$text 二维码的文字
参数2$uid 中间用户头像的uid
参数3$level 码块的大小等级
参数4$size 二维码的大小
返回值返回二维码地址

过滤非排序参数的法字段
dr_get_order_string($str, $order)
参数1$str 字符串
参数2$order 排序方式
返回值过滤后的值

两价格的折扣值
dr_discount($price, $nowprice)
参数1$price 当前价格
参数2$nowprice 以前的价格
返回值计算后的值

根据两点间的经纬度计算距离
dr_distance($new, $to, $mark = '米,千米')
参数1$new 当前坐标
参数2$to 目标坐标
参数3$mark 单位
返回值返回距离

计算某个经纬度的周围某段距离的正方形的四个点
dr_square_point($lng, $lat, $distance = 0.5)
参数1$lng float 经度
参数2$lat float 纬度
参数3$distance float 该点所在圆的半径,该圆与此正方形内切,默认值为0.5千米
返回值array 正方形的四个点的经纬度坐标

获取当前模板目录
dr_tpl_path($is_member = IS_MEMBER)

数组随机排序,并截取数组
dr_array_rand($arr, $num = 0)
参数1$arr
参数2$num 数量
返回值新数组

数组的指定元素大小排序
dr_array_sort($arr, $key, $type = 'asc')
参数1$arr
参数2$key KEY键名
参数3$type 排序方式 asc desc
返回值新数组

获取网站表单发布页面需要的变量值
dr_get_form_post_value($table, $siteid = SITE_ID)

获取模块表单发布页面需要的变量值
dr_get_mform_post_value($mid, $table, $cid, $siteid = SITE_ID)

获取用户注册页面需要的变量值
dr_get_register_value($groupid = 0, $url = '')

获取当前模板文件路径
dr_tpl_file($file)
参数1$file 模板名
返回值返回完整名

兼容统计count函数
dr_count($array_or_countable, $mode = COUNT_NORMAL)

给地址补全https或者http前缀
dr_http_prefix($url)

转换url
dr_to_url($url, $domian = '', $siteid = SITE_ID)
参数1$Url 指定地址
参数2$domian 指定域名 或者 模块目录
参数3int|string $siteid 站点id号
返回值新的url

获取对应的手机端地址
dr_mobile_url($url = SITE_MURL)
参数1$url 任意域名
返回值新的url

是否是完整的url
dr_is_url($url)
参数1$url
返回值boolean

补全url
dr_url_prefix($url, $domain = '', $siteid = SITE_ID, $is_mobile = '')
参数1$url
参数2string $domain 指定域名或者模块目录
参数3int|string $siteid 站点ID
参数4string $is_mobile 是否指定为移动端
返回值新的url

补全相对路径
dr_web_prefix($url)
参数1$url
返回值新的url

url转为完整路径 URL补全
dr_url_full($url, $prefix = '')
参数1$url
参数2$prefix 指定替换域名/
返回值新的url

url转为相对路径
dr_url_rel($url, $prefix = '')
参数1$url
参数2$prefix 将指定字符串替换成/
返回值新的url

内容中的转为相对路径
dr_text_rel($text, $prefix = '', $attr = ['href', 'src'])
参数1$text
参数2$prefix 将指定字符串替换成/
参数3$attr 将指定替换哪些标签 ['href', 'src']
返回值新的内容

内容中的转为完整路径,地址补全绝对路径
dr_text_full($text, $url = SITE_URL, $attr = ['href', 'src'])
参数1$text
参数2$url 将/替换成哪个地址
参数3$attr 将指定替换哪些标签 ['href', 'src']
返回值新的内容

计算用户组到期时间
dr_member_group_etime($days, $dtype, $ntime = 0)
参数1$days 天数
参数2$dtype 到期换算单位
参数3$ntime 时间基数,默认为当前时间
返回值是否到期

用户组到期时间单位
dr_member_group_dtype($dtype)
参数1$dtype 到期换算单位
返回值单位

处理带Emoji的数据,HTML转为emoji码
dr_html2emoji($msg)
参数1$msg 转换字符串
返回值新的字符串

过滤emoji表情
dr_clear_emoji($str)
参数1type $str
返回值新的字符串

文字转换拼音
dr_text2py($str)
参数1$str
返回值新的字符串

将html转化为纯文字
dr_html2text($str, $cn = false)
参数1$str
参数2$cn 是否纯中文
返回值新的字符串

批量 htmlspecialchars
dr_htmlspecialchars($param)

当前是否是根目录
dr_is_root_path()

检查目录权限
dr_check_put_path($dir)
参数1$dir 目录地址
返回值逻辑值

存储调试信息
dr_debug($file, $data)
参数1file 存储文件
参数2data 打印变量
返回值

转为utf8编码格式
dr_code2utf8($str)
参数1$str 来源字符串

清除HTML标记@param string $str@return string
dr_clearhtml($str)

提取描述信息过滤函数
dr_filter_description($value, $data = [], $old = [])

提取描述信息
dr_get_description($text, $limit = 0)

提取关键字
dr_get_keywords($kw, $siteid = SITE_ID)

跳转地址
dr_redirect($url = '', $method = 'auto', $code = 0)

跳转地址安全检测
dr_redirect_safe_check($url)

移除不规则的字符串
remove_invisible_characters($str, $urlEncoded = true)