first commit
This commit is contained in:
49
extend/tools/Behavior.php
Normal file
49
extend/tools/Behavior.php
Normal 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
71
extend/tools/Config.php
Normal 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
99
extend/tools/Crypt.php
Normal 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
241
extend/tools/Database.php
Normal 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
26
extend/tools/Format.php
Normal 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
104
extend/tools/Initialize.php
Normal 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
214
extend/tools/Pager.php
Normal 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 = "«")
|
||||
{
|
||||
|
||||
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 = '»')
|
||||
{
|
||||
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
235
extend/tools/Str.php
Normal 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
107
extend/tools/Time.php
Normal 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
90
extend/tools/Tree.php
Normal 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(" ", $level * 4);
|
||||
$tmp_str .= "└ ";
|
||||
$val['level'] = $level;
|
||||
$val['title_show'] = $level == 0 ? $val[$title] . " " : $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
90
extend/tools/Verify.php
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user