1
0

first commit

This commit is contained in:
2020-08-06 14:58:51 +08:00
commit 17096657dc
780 changed files with 92857 additions and 0 deletions

49
extend/tools/Behavior.php Normal file
View File

@@ -0,0 +1,49 @@
<?php
// +------------------------------------------------+
// |http://www.cjango.com |
// +------------------------------------------------+
// | 修复BUG不是一朝一夕的事情等我喝醉了再说吧 |
// +------------------------------------------------+
// | Author: 小陈叔叔 <Jason.Chen> |
// +------------------------------------------------+
namespace tools;
use think\Request;
class Behavior
{
/**
* 加载系统配置
*/
public function appBegin()
{
Config::load();
define('__SELF__', Request::instance()->url(true));
}
/**
* 定义系统常量
*/
public function moduleInit()
{
$request = Request::instance();
$method = $request->method();
define('IS_GET', $method == 'GET' ? true : false);
define('IS_POST', $method == 'POST' ? true : false);
define('IS_AJAX', $request->isAjax());
define('MODULE_NAME', $request->module());
define('CONTROLLER_NAME', $request->controller());
define('ACTION_NAME', $request->action());
}
/**
* 返回头修改
*/
public function appEnd(&$response)
{
$response->header('X-Powered-By', 'cjango.com');
}
}

71
extend/tools/Config.php Normal file
View File

@@ -0,0 +1,71 @@
<?php
// +------------------------------------------------+
// |http://www.cjango.com |
// +------------------------------------------------+
// | 修复BUG不是一朝一夕的事情等我喝醉了再说吧 |
// +------------------------------------------------+
// | Author: 小陈叔叔 <Jason.Chen> |
// +------------------------------------------------+
namespace tools;
use think\Cache;
use think\Config as Conf;
use think\Db;
/**
* 加载系统配置,依赖数据库和缓存
*/
class Config
{
/**
* 加载系统扩展配置
*/
public static function load()
{
$config = Cache::get('db_config_cache_data');
if (!$config) {
$data = Db::name('Config')->where('status', 1)->field('type,name,value')->select();
$config = [];
if ($data && is_array($data)) {
foreach ($data as $value) {
$config[$value['name']] = self::parse($value['type'], $value['value']);
}
}
Cache::set('db_config_cache_data', $config);
}
Conf::set($config);
}
/**
* 根据配置类型解析配置
* @param integer $type 配置类型
* @param string $value 配置值
* @return array
*/
private static function parse($type, $value)
{
switch ($type) {
case 3: //解析数组
$array = preg_split('/[\r\n]+/', trim($value, "\r\n"));
if (strpos($value, ':')) {
$value = [];
foreach ($array as $val) {
list($k, $v) = explode(':', $val, 2);
$value[$k] = $v;
}
} else {
$value = $array;
}
break;
}
return $value;
}
/**
* 清除配置缓存
*/
public static function clear()
{
Cache::rm('db_config_cache_data');
}
}

99
extend/tools/Crypt.php Normal file
View File

@@ -0,0 +1,99 @@
<?php
// +------------------------------------------------+
// |http://www.cjango.com |
// +------------------------------------------------+
// | 修复BUG不是一朝一夕的事情等我喝醉了再说吧 |
// +------------------------------------------------+
// | Author: 小陈叔叔 <Jason.Chen> |
// +------------------------------------------------+
namespace tools;
use think\Config as Conf;
class Crypt
{
/**
* 数据签名认证
* @param array $data
* @return string
*/
public static function dataAuthSign($data = [])
{
ksort($data);
$code = http_build_query($data);
return sha1($code . Conf::get('data_auth_key'));
}
/**
* 用户MD5不可逆加密
* @param string $string
* @return string
*/
public static function uMd5($string)
{
$key = Conf::get('data_auth_key');
return '' === $string ? '' : md5(sha1($string) . $key);
}
/**
* 长串加密
* @param string $string
* @return string
*/
public static function uSha1($string)
{
$key = Conf::get('data_auth_key');
return '' === $string ? '' : sha1(md5($string) . $key);
}
/**
* Discuz 经典双向加密/解密
* @param string $string 明文 或 密文
* @param string $operation DECODE表示解密,其它表示加密
* @param string $key 密匙
* @param string $expiry 密文有效期
*/
public static function discuz($string, $operation = 'DECODE', $key = '', $expiry = 0)
{
$ckey_length = 4;
$key = md5($key ? $key : Conf::get('data_auth_key'));
$keya = md5(substr($key, 0, 16));
$keyb = md5(substr($key, 16, 16));
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length) : substr(md5(microtime()), -$ckey_length)) : '';
$cryptkey = $keya . md5($keya . $keyc);
$key_length = strlen($cryptkey);
$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) . $string;
$string_length = strlen($string);
$result = '';
$box = range(0, 255);
$rndkey = [];
for ($i = 0; $i <= 255; $i++) {
$rndkey[$i] = ord($cryptkey[$i % $key_length]);
}
for ($j = $i = 0; $i < 256; $i++) {
$j = ($j + $box[$i] + $rndkey[$i]) % 256;
$tmp = $box[$i];
$box[$i] = $box[$j];
$box[$j] = $tmp;
}
for ($a = $j = $i = 0; $i < $string_length; $i++) {
$a = ($a + 1) % 256;
$j = ($j + $box[$a]) % 256;
$tmp = $box[$a];
$box[$a] = $box[$j];
$box[$j] = $tmp;
$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
}
if ($operation == 'DECODE') {
if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16)) {
return substr($result, 26);
} else {
return '';
}
} else {
return $keyc . str_replace('=', '', base64_encode($result));
}
}
}

241
extend/tools/Database.php Normal file
View File

@@ -0,0 +1,241 @@
<?php
// +------------------------------------------------+
// | http://www.cjango.com |
// +------------------------------------------------+
// | 修复BUG不是一朝一夕的事情等我喝醉了再说吧 |
// +------------------------------------------------+
// | Author: 小陈叔叔 <Jason.Chen> |
// +------------------------------------------------+
namespace tools;
/**
* 数据导出工具
*/
class Database
{
/**
* 文件指针
* @var resource
*/
private $fp;
/**
* 备份文件信息 part - 卷号name - 文件名
* @var array
*/
private $file;
/**
* 当前打开文件大小
* @var integer
*/
private $size = 0;
/**
* 备份配置
* @var integer
*/
private $config = [
'path' => '', // 数据库备份根路径
'part' => 2097152, // 数据库备份卷大小 2Mb
'compress' => true, // 数据库备份文件是否启用压缩
'level' => 9, // 数据库备份文件压缩级别
'line' => 1000,
];
/**
* 数据库备份构造方法
* @param array $file 备份或还原的文件信息
* @param array $config 备份配置信息
*/
public function __construct($file, $config)
{
$this->file = $file;
$this->config = array_merge($this->config, $config);
}
/**
* 打开一个卷,用于写入数据
* @param integer $size 写入数据的大小
*/
private function open($size)
{
if ($this->fp) {
$this->size += $size;
if ($this->size > $this->config['part']) {
$this->config['compress'] ? @gzclose($this->fp) : @fclose($this->fp);
$this->fp = null;
$this->file['part']++;
session('backup_file', $this->file);
$this->create();
}
} else {
$backuppath = $this->config['path'];
$filename = "{$backuppath}{$this->file['name']}-{$this->file['part']}.sql";
if ($this->config['compress']) {
$filename = "{$filename}.gz";
$this->fp = @gzopen($filename, "a{$this->config['level']}");
} else {
$this->fp = @fopen($filename, 'a');
}
$this->size = filesize($filename) + $size;
}
}
/**
* 写入初始数据
* @return boolean true - 写入成功false - 写入失败
*/
public function create()
{
$sql = "-- -----------------------------\n";
$sql .= "-- c.Jango MySQL Data Transfer\n";
$sql .= "--\n";
$sql .= "-- Host : " . \think\Config::get('database.hostname') . "\n";
$sql .= "-- UserName : " . \think\Config::get('database.username') . "\n";
$sql .= "-- Database : " . \think\Config::get('database.database') . "\n";
$sql .= "--\n";
$sql .= "-- Part : #{$this->file['part']}\n";
$sql .= "-- Date : " . date("Y-m-d H:i:s") . "\n";
$sql .= "-- -----------------------------\n\n";
return $this->write($sql);
}
/**
* 写入SQL语句
* @param string $sql 要写入的SQL语句
* @return boolean true - 写入成功false - 写入失败!
*/
private function write($sql)
{
$size = strlen($sql);
// 由于压缩原因无法计算出压缩后的长度这里假设压缩率为50%
// 一般情况压缩率都会高于50%
$size = $this->config['compress'] ? $size / 2 : $size;
$this->open($size);
return $this->config['compress'] ? @gzwrite($this->fp, $sql) : @fwrite($this->fp, $sql);
}
/**
* 备份表结构
* @param string $table 表名
* @param integer $start 起始行数
* @return boolean false - 备份失败
*/
public function backup($table, $start)
{
// 创建DB对象
$db = \think\Loader::db();
// 备份表结构
if (0 == $start) {
$result = $db->query("SHOW CREATE TABLE `{$table}`");
$result = array_change_key_case($result[0]);
$sql = "\n";
$sql .= "-- -----------------------------\n";
$sql .= "-- Table structure for `{$table}`\n";
$sql .= "-- -----------------------------\n";
$sql .= "SET FOREIGN_KEY_CHECKS = 0;\n";
$sql .= "DROP TABLE IF EXISTS `{$table}`;\n";
$sql .= trim($result['create table']) . ";\n\n";
if (false === $this->write($sql)) {
return false;
}
}
// 数据总数
$result = $db->query("SELECT COUNT(*) AS count FROM `{$table}`");
$count = $result[0]['count'];
$line = $this->config['line'];
// 备份表数据
if ($count) {
// 写入数据注释
if (0 == $start) {
$sql = "-- -----------------------------\n";
$sql .= "-- Records of `{$table}`\n";
$sql .= "-- -----------------------------\n";
$this->write($sql);
}
// 备份数据记录
$result = $db->query("SELECT * FROM `{$table}` LIMIT {$start}, $line");
$columns = $db->query("SHOW COLUMNS FROM `{$table}`");
$columns = array_column($columns, 'Field');
$columns = implode('`, `', $columns);
$sql = "INSERT INTO `{$table}` (`{$columns}`) VALUES\r\n";
foreach ($result as $row) {
$sql .= "('" . str_replace(["\r", "\n"], ['\r', '\n'], implode("', '", $row)) . "'),\r\n";
}
$sql = rtrim(rtrim($sql), ',') . ";\r\n";
if (false === $this->write($sql)) {
return false;
}
// 还有更多数据
if ($count > $start + $line) {
return [$start + $line, $count];
}
}
// 备份下一表
return 0;
}
/**
* 还原数据库
* @param integer $start [description]
* @return [type] [description]
*/
public function import($start = 0)
{
//还原数据
$db = \think\Loader::db();
if ($this->config['compress']) {
$gz = gzopen($this->file[1], 'r');
$size = 0;
} else {
$size = filesize($this->file[1]);
$gz = fopen($this->file[1], 'r');
}
$sql = '';
if ($start) {
$this->config['compress'] ? gzseek($gz, $start) : fseek($gz, $start);
}
for ($i = 0; $i < 1000; $i++) {
$sql .= $this->config['compress'] ? gzgets($gz) : fgets($gz);
if (preg_match('/.*;$/', trim($sql))) {
if (false !== $db->execute($sql)) {
$start += strlen($sql);
} else {
return false;
}
$sql = '';
} elseif ($this->config['compress'] ? gzeof($gz) : feof($gz)) {
return 0;
}
}
return [$start, $size];
}
/**
* 析构方法,用于关闭文件资源
*/
public function __destruct()
{
if ($this->config['compress'] && !is_null($this->fp)) {
@gzclose($this->fp);
} elseif (!is_null($this->fp)) {
@fclose($this->fp);
} else {
}
}
}

26
extend/tools/Format.php Normal file
View File

@@ -0,0 +1,26 @@
<?php
// +------------------------------------------------+
// |http://www.cjango.com |
// +------------------------------------------------+
// | 修复BUG不是一朝一夕的事情等我喝醉了再说吧 |
// +------------------------------------------------+
// | Author: 小陈叔叔 <Jason.Chen> |
// +------------------------------------------------+
namespace tools;
class Format
{
/**
* 格式化字节数显示
* @param integer $value
* @return string
*/
public static function byte($value)
{
$units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
for ($i = 0; $value >= 1024 && $i < 5; $i++) {
$value /= 1024;
}
return round($value, 2) . $units[$i];
}
}

104
extend/tools/Initialize.php Normal file
View File

@@ -0,0 +1,104 @@
<?php
// +------------------------------------------------+
// |http://www.cjango.com |
// +------------------------------------------------+
// | 修复BUG不是一朝一夕的事情等我喝醉了再说吧 |
// +------------------------------------------------+
// | Author: 小陈叔叔 <Jason.Chen> |
// +------------------------------------------------+
namespace tools;
use cjango\Wechat;
use cjango\Wechat\Token;
use think\Cache;
use think\Config;
use think\Controller;
use think\Session;
/**
* 所有模块的公共方法
*/
class Initialize extends Controller
{
/**
* 判断是否登录返回当前UID
* @return integer
*/
final protected static function isLogin()
{
$user = Session::get('user_auth');
if (empty($user)) {
return 0;
} else {
return Session::get('user_auth_sign') == Crypt::dataAuthSign($user) ? $user['uid'] : 0;
}
}
/**
* 初始化微信
* @return void
*/
protected function initWechat()
{
$token = Cache::get('wechat_access_token');
$config = Config::get('wechat');
if (!$token) {
Wechat::instance($config);
$token = Token::get();
Cache::set('wechat_access_token', $token, 7200);
$config['access_token'] = $token;
Wechat::instance($config, true);
} else {
$config['access_token'] = $token;
Wechat::instance($config);
}
}
/**
* 微信分享
*/
protected function jsWechat()
{
$ticket = Cache::get('Wechat_ticket');
$config = Config::get('wechat_config');
self::initWechat();
if (!$ticket) {
$ticket = Token::ticket();
Cache::set('Wechat_ticket', $ticket, 7000);
}
$now_time = time();
$wx['appid'] = $config['appid'];
$wx['timestamp'] = $now_time;
$wx['noncestr'] = $noncestr = \tools\Str::random(32);
$sign = array(
'noncestr' => $noncestr,
'jsapi_ticket' => $ticket,
'timestamp' => $now_time,
'url' => __SELF__,
);
ksort($sign);
$signStr = sha1(urldecode(http_build_query($sign)));
$wx['signature'] = $signStr;
return $wx;
}
/**
* 模板变量赋值
* @param string $name 变量名
* @param mixed $value 变量值
*/
final public function __set($name, $value)
{
$this->view->$name = $value;
}
/**
* 取得模板显示变量的值
* @param string $name 模板变量
* @return mixed|null
*/
final public function __get($name)
{
return $this->view->$name ?? null;
}
}

214
extend/tools/Pager.php Normal file
View File

@@ -0,0 +1,214 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: zhangyajun <448901948@qq.com>
// +----------------------------------------------------------------------
namespace tools;
use think\Paginator;
class Pager extends Paginator
{
/**
* 上一页按钮
* @param string $text
* @return string
*/
protected function getPreviousButton($text = "&laquo;")
{
if ($this->currentPage() <= 1) {
return $this->getDisabledTextWrapper($text);
}
$url = $this->url(
$this->currentPage() - 1
);
return $this->getPageLinkWrapper($url, $text);
}
/**
* 下一页按钮
* @param string $text
* @return string
*/
protected function getNextButton($text = '&raquo;')
{
if (!$this->hasMore) {
return $this->getDisabledTextWrapper($text);
}
$url = $this->url($this->currentPage() + 1);
return $this->getPageLinkWrapper($url, $text);
}
/**
* 页码按钮
* @return string
*/
protected function getLinks()
{
if ($this->simple) {
return '';
}
$block = [
'first' => null,
'slider' => null,
'last' => null,
];
$length = 3;
if ($this->lastPage < $length * 4) {
$block['first'] = $this->getUrlRange(1, $this->lastPage);
} elseif ($this->currentPage <= $length * 2) {
$block['first'] = $this->getUrlRange(1, $length * 2 + 2);
$block['last'] = $this->getUrlRange($this->lastPage - 1, $this->lastPage);
} elseif ($this->currentPage > ($this->lastPage - $length * 2)) {
$block['first'] = $this->getUrlRange(1, 2);
$block['last'] = $this->getUrlRange($this->lastPage - $length * 2 + 2, $this->lastPage);
} else {
$block['first'] = $this->getUrlRange(1, 2);
$block['slider'] = $this->getUrlRange($this->currentPage - $length, $this->currentPage + $length);
$block['last'] = $this->getUrlRange($this->lastPage - 1, $this->lastPage);
}
$html = '';
if (is_array($block['first'])) {
$html .= $this->getUrlLinks($block['first']);
}
if (is_array($block['slider'])) {
$html .= $this->getDots();
$html .= $this->getUrlLinks($block['slider']);
}
if (is_array($block['last'])) {
$html .= $this->getDots();
$html .= $this->getUrlLinks($block['last']);
}
return $html;
}
/**
* 渲染分页html
* @return mixed
*/
public function render()
{
if ($this->hasPages()) {
if ($this->simple) {
return sprintf(
'<ul class="pager">%s %s</ul>',
$this->getPreviousButton(),
$this->getNextButton()
);
} else {
return sprintf(
'<ul class="pager">%s %s %s %s</ul>',
$this->getPreviousButton(),
$this->getLinks(),
$this->getNextButton(),
$this->getTotalCountWrapper()
);
}
}
}
/**
* 获取分页总数统计
* @return [type] [description]
*/
protected function getTotalCountWrapper()
{
return '<li><span>总' . $this->total() . '条/' . $this->lastPage() . '页</span></li>';
}
/**
* 生成一个可点击的按钮
*
* @param string $url
* @param int $page
* @return string
*/
protected function getAvailablePageWrapper($url, $page)
{
return '<li><a href="' . htmlentities($url) . '">' . $page . '</a></li>';
}
/**
* 生成一个禁用的按钮
*
* @param string $text
* @return string
*/
protected function getDisabledTextWrapper($text)
{
return '<li class="disabled"><span>' . $text . '</span></li>';
}
/**
* 生成一个激活的按钮
*
* @param string $text
* @return string
*/
protected function getActivePageWrapper($text)
{
return '<li class="active"><span>' . $text . '</span></li>';
}
/**
* 生成省略号按钮
*
* @return string
*/
protected function getDots()
{
return $this->getDisabledTextWrapper('...');
}
/**
* 批量生成页码按钮.
*
* @param array $urls
* @return string
*/
protected function getUrlLinks(array $urls)
{
$html = '';
foreach ($urls as $page => $url) {
$html .= $this->getPageLinkWrapper($url, $page);
}
return $html;
}
/**
* 生成普通页码按钮
*
* @param string $url
* @param int $page
* @return string
*/
protected function getPageLinkWrapper($url, $page)
{
if ($page == $this->currentPage()) {
return $this->getActivePageWrapper($page);
}
return $this->getAvailablePageWrapper($url, $page);
}
}

235
extend/tools/Str.php Normal file
View File

@@ -0,0 +1,235 @@
<?php
// +------------------------------------------------+
// |http://www.cjango.com |
// +------------------------------------------------+
// | 修复BUG不是一朝一夕的事情等我喝醉了再说吧 |
// +------------------------------------------------+
// | Author: 小陈叔叔 <Jason.Chen> |
// +------------------------------------------------+
namespace tools;
/**
* 字符串辅助函数
*/
class Str
{
/**
* 生成UUID 单机使用
* @access public
* @return string
*/
public static function uuid()
{
$charid = self::guid();
$hyphen = chr(45);
$uuid = substr($charid, 0, 8) . $hyphen
. substr($charid, 8, 4) . $hyphen
. substr($charid, 12, 4) . $hyphen
. substr($charid, 16, 4) . $hyphen
. substr($charid, 20, 12);
return $uuid;
}
/**
* 生成GUID主键
* @return string
*/
public static function guid()
{
return md5(uniqid(mt_rand(), true));
}
/**
* 检查字符串是否是UTF8编码
* @param string $string 字符串
* @return boolean
*/
public static function isUtf8($str)
{
$c = 0;
$b = 0;
$bits = 0;
$len = strlen($str);
for ($i = 0; $i < $len; $i++) {
$c = ord($str[$i]);
if ($c > 128) {
if (($c >= 254)) {
return false;
} elseif ($c >= 252) {
$bits = 6;
} elseif ($c >= 248) {
$bits = 5;
} elseif ($c >= 240) {
$bits = 4;
} elseif ($c >= 224) {
$bits = 3;
} elseif ($c >= 192) {
$bits = 2;
} else {
return false;
}
if (($i + $bits) > $len) {
return false;
}
while ($bits > 1) {
$i++;
$b = ord($str[$i]);
if ($b < 128 || $b > 191) {
return false;
}
$bits--;
}
}
}
return true;
}
/**
* 字符串截取,支持中文和其他编码
* @param string $str 需要转换的字符串
* @param string $start 开始位置
* @param string $length 截取长度
* @param string $suffix 截断显示字符/或拼接字符
* @param string $charset 编码格式
* @return string
*/
public static function msubstr($str, $start, $length, $suffix = true, $charset = "utf-8")
{
if (mb_strlen($str, $charset) < $length) {
return $str;
}
if (function_exists("mb_substr")) {
$slice = mb_substr($str, $start, $length, $charset);
} elseif (function_exists('iconv_substr')) {
$slice = iconv_substr($str, $start, $length, $charset);
} else {
$re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
$re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
$re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
$re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
preg_match_all($re[$charset], $str, $match);
$slice = join("", array_slice($match[0], $start, $length));
}
if (is_bool($suffix)) {
return $suffix ? $slice . '..' : $slice;
} else {
return $slice . $suffix;
}
}
/**
* 产生随机字串,可用来自动生成密码
* 默认长度6位 字母和数字混合
* @param string $len 长度
* @param string $type 字串类型
* 0 字母 1 数字 其它 混合
* @param string $addChars 额外字符
* @return string
*/
public static function random($len = 6, $type = '', $addChars = '')
{
$str = '';
switch ($type) {
case 0:
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' . $addChars;
break;
case 1:
$chars = str_repeat('0123456789', 3);
break;
case 2:
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' . $addChars;
break;
case 3:
$chars = 'abcdefghijklmnopqrstuvwxyz' . $addChars;
break;
default:
$chars = 'ABCDEFGHIJKMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789' . $addChars;
break;
}
if ($len > 10) {
$chars = $type == 1 ? str_repeat($chars, $len) : str_repeat($chars, 5);
}
$chars = str_shuffle($chars);
$str = substr($chars, 0, $len);
return $str;
}
/**
* 生成一定数量的随机数,并且不重复
* @param integer $number 数量
* @param integer $len 长度
* @param integer $type 字串类型
* @param integer $mode 0 字母 1 数字 其它 混合
* @return array
*/
public static function randomArray($number, $length = 4, $mode = 1)
{
$rand = [];
for ($i = 0; $i < $number; $i++) {
$rand[] = self::random($length, $mode);
}
$unqiue = array_unique($rand);
if (count($unqiue) == count($rand)) {
return $rand;
}
$count = count($rand) - count($unqiue);
for ($i = 0; $i < $count * 3; $i++) {
$rand[] = self::random($length, $mode);
}
$rand = array_slice(array_unique($rand), 0, $number);
return $rand;
}
/**
* 获取一定范围内的随机数字 位数不足补零
* @param integer $min 最小值
* @param integer $max 最大值
* @return string
*/
public static function number($min, $max)
{
return sprintf("%0" . strlen($max) . "d", mt_rand($min, $max));
}
/**
* 创建一个20位的数字订单号
* @param string $prefix 订单号前缀
* @return string
*/
public static function orderid($prefix = '', $length = 20)
{
$code = date('ymdHis') . self::number(0, 99999999);
if (!empty($prefix)) {
$code = $prefix . substr($code, 0, $length - strlen($prefix));
}
return $code;
}
/**
* 短网址生成算法
* @param string $url 要计算的URL
* @return string
*/
public static function url($url)
{
$charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
$key = "Uncle.Chen";
$date = microtime();
$urlhash = md5($key . $url . $date);
$len = strlen($urlhash);
for ($i = 0; $i < 4; $i++) {
$urlhash_piece = substr($urlhash, $i * $len / 4, $len / 4);
$hex = hexdec($urlhash_piece) & 0x3fffffff;
$short_url = "";
for ($j = 0; $j < 6; $j++) {
$short_url .= $charset[$hex & 0x0000003d];
$hex = $hex >> 5;
}
$short_url_list[] = $short_url;
}
$ret = rand(0, 3);
return $short_url_list[$ret];
}
}

107
extend/tools/Time.php Normal file
View File

@@ -0,0 +1,107 @@
<?php
// +------------------------------------------------+
// |http://www.cjango.com |
// +------------------------------------------------+
// | 修复BUG不是一朝一夕的事情等我喝醉了再说吧 |
// +------------------------------------------------+
// | Author: 小陈叔叔 <Jason.Chen> |
// +------------------------------------------------+
namespace tools;
/**
* 时间戳生成类
*/
class Time
{
/**
* [今日/某日 开始和结束的时间戳]
* @param date $date 标准的时间日期格式 Y-m-d
* @return boolean|array
*/
public static function day($date = '', $rule = 'Y-m-d')
{
if (!empty($date) && !Verify::isDate($date, $rule)) {
return false;
}
$date = !empty($date) ? $date : 'today';
$start = strtotime($date);
$end = $start + 86399;
return [$start, $end];
}
/**
* 返回本周开始和结束的时间戳
* @return array
*/
public static function week()
{
$timestamp = time();
return [
strtotime(date('Y-m-d', strtotime("+0 week Monday", $timestamp))),
strtotime(date('Y-m-d', strtotime("+0 week Sunday", $timestamp))) + 24 * 3600 - 1,
];
}
/**
* 返回本月开始和结束的时间戳
* @return array
*/
public static function month($month = '', $year = '')
{
if (empty($month)) {
$month = date('m');
} elseif (!is_numeric($month) || $month < 1 || $month > 12) {
return false;
}
if (empty($year)) {
$year = date('Y');
} elseif (!is_numeric($year) || $year < 1970 || $year > 2038) {
return false;
}
$start = mktime(0, 0, 0, $month, 1, $year);
$end = mktime(23, 59, 59, $month, date('t', $start), $year);
return [$start, $end];
}
/**
* 今年/某年 开始和结束的时间戳
* @return boolean|array
*/
public static function year($year = '')
{
if (empty($year)) {
$year = date('Y');
} elseif (!is_numeric($year) || $year < 1970 || $year > 2038) {
return false;
}
return [
mktime(0, 0, 0, 1, 1, $year),
mktime(23, 59, 59, 12, 31, $year),
];
}
/**
* [日期合法性校验]
* @param [type] $data 2019-01-01
* @return boolean
*/
public static function dateVerify($date, $rule = 'Y-m-d')
{
$unixTime = strtotime($date);
if (!$unixTime) {
return false;
}
if (date($rule, $unixTime) == $date) {
return true;
} else {
return false;
}
}
}

90
extend/tools/Tree.php Normal file
View File

@@ -0,0 +1,90 @@
<?php
// +------------------------------------------------+
// | http://www.cjango.com |
// +------------------------------------------------+
// | 修复BUG不是一朝一夕的事情等我喝醉了再说吧 |
// +------------------------------------------------+
// | Author: 小陈叔叔 <Jason.Chen> |
// +------------------------------------------------+
namespace tools;
/**
* 生成多层树状下拉选框的工具
*/
class Tree
{
/**
* 用于树型数组完成递归格式的全局变量
*/
private static $formatTree;
/**
* 生成多层树,供下拉选框使用
*/
public static function toFormatTree($list, $title = 'title', $pk = 'id', $pid = 'pid', $root = 0)
{
$list = self::list2tree($list, $pk, $pid, '_child', $root);
self::$formatTree = [];
self::_toFormatTree($list, 0, $title);
return self::$formatTree;
}
/**
* 把数据集转换成Tree
* @param array $list 要转换的数据集
* @param string $pk [description]
* @param string $pid [description]
* @param string $child [description]
* @param integer $root [description]
* @return array
*/
public static function list2tree($list, $pk = 'id', $pid = 'pid', $child = 'children', $root = 0)
{
$tree = [];
if (is_array($list)) {
$refer = [];
foreach ($list as $key => $data) {
$refer[$data[$pk]] = &$list[$key];
}
foreach ($list as $key => $data) {
$parentId = $data[$pid];
if ($root == $parentId) {
$tree[] = &$list[$key];
} else {
if (isset($refer[$parentId])) {
$parent = &$refer[$parentId];
$parent[$child][] = &$list[$key];
}
}
}
}
return $tree;
}
/**
* 将格式数组转换为树
* @param array $list
* @param integer $level 进行递归时传递用的参数
* @author 小陈叔叔 <Jason.Chen[cjango.com]>
*/
private static function _toFormatTree($list, $level = 0, $title = 'title')
{
foreach ($list as $key => $val) {
$tmp_str = str_repeat("&nbsp;", $level * 4);
$tmp_str .= "└&nbsp;";
$val['level'] = $level;
$val['title_show'] = $level == 0 ? $val[$title] . "&nbsp;" : $tmp_str . $val[$title];
if (!array_key_exists('_child', $val)) {
array_push(self::$formatTree, $val);
} else {
$tmp_ary = $val['_child'];
unset($val['_child']);
array_push(self::$formatTree, $val);
self::_toFormatTree($tmp_ary, $level + 1, $title); //进行下一层递归
}
}
return;
}
}

90
extend/tools/Verify.php Normal file
View File

@@ -0,0 +1,90 @@
<?php
// +------------------------------------------------+
// |http://www.cjango.com |
// +------------------------------------------------+
// | 修复BUG不是一朝一夕的事情等我喝醉了再说吧 |
// +------------------------------------------------+
// | Author: 小陈叔叔 <Jason.Chen> |
// +------------------------------------------------+
namespace tools;
/**
* 校验工具类
*/
class Verify
{
/**
* 身份证号码校验
* @param string $idcard
* @return boolean
*/
public static function isIdcard($cardNo)
{
if (strlen($cardNo) != 18) {
return false;
}
$idcard_base = substr($cardNo, 0, 17);
$verify_code = substr($cardNo, 17, 1);
$factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
$verify_list = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
$total = 0;
for ($i = 0; $i < 17; $i++) {
$total += substr($idcard_base, $i, 1) * $factor[$i];
}
$mod = $total % 11;
if ($verify_code == $verify_list[$mod]) {
return true;
} else {
return false;
}
}
/**
* 检测手机号码格式
* @param string $mobile
* @return boolean
*/
public static function isMobilePhone($mobile)
{
if (preg_match("/^1[3578]{1}[0-9]{9}$|14[57]{1}[0-9]{8}$/", $mobile)) {
return true;
} else {
return false;
}
}
/**
* JSON校验
* @param string $jsonStr
* @return boolean
*/
public static function isJson($jsonStr)
{
if (!is_object(json_decode($jsonStr))) {
return false;
} else {
return true;
}
}
/**
* 校验日期格式是否合法
* @param [type] $date 日期
* @param string $rule 要校验的格式
* @return boolean
*/
public static function isDate($date, $rule = 'Y-m-d')
{
$unixTime = strtotime($date);
if (!$unixTime || date($rule, $unixTime) != $date) {
return false;
} else {
return true;
}
}
}