首页
友人帐
留言板
关于
Search
1
IDE Eval Resetter:JetBrains 全家桶无限试用插件
382 阅读
2
影视资源采集站收录大全
305 阅读
3
linux安装或升级protoc
224 阅读
4
VFM 3.7.5 源码 - 一个极简的 PHP 私人云盘!
161 阅读
5
批量采集美女写真等图片做图片站
149 阅读
谈天说地
程序源码
技术教程
成品源码
登录
Search
标签搜索
PHP
linux
源码
go
windows
centos
原创
mysql
微信
激活
采集
宝塔
绿色版
API
解析
SDK
图片
破解
域名
html
云青
累计撰写
150
篇文章
累计收到
79
条评论
首页
栏目
谈天说地
程序源码
技术教程
成品源码
页面
友人帐
留言板
关于
搜索到
92
篇与
的结果
2021-07-10
golang cron v3 定时任务实现
最近需要在 golang 中使用定时任务功能,用到了一个 cron 库,当前是 v3 版本,网上挺多都是 v2 的教程,记录一下使用方法。在旧版本的库中默认的 cron 表达式不是标准格式,第一个位是秒级的定义。现在 v3 版本直接用标准 cron 表示式即可,主要看 godoc 文档部分cron 表示式推荐使用在线工具来看自己写的 cron 对不对,简单的表达式直接写一般问题不大。这里推荐 crontab.guru,可以通过可视化的方式来查看你编写的定时规则。以下内容摘自 维基百科-Cron文件格式說明┌──分鐘(0 - 59) │ ┌──小時(0 - 23) │ │ ┌──日(1 - 31) │ │ │ ┌─月(1 - 12) │ │ │ │ ┌─星期(0 - 6,表示从周日到周六) │ │ │ │ │ * * * * * 被執行的命令注:在某些系统里,星期日也可以为 7不很直观的用法:如果日期和星期同时被设定,那么其中的一个条件被满足时,指令便会被执行。请参考下例。前 5 个域称之分时日月周,可方便个人记忆。从第六个域起,指明要执行的命令。安装现在都是用的 Go module 进行模块的管理,直接在 goland 中使用 alt + 回车即可同步对应的包 “github.com/robfig/cron/v3”使用 go get 安装方式如下go get github.com/robfig/cron/v3创建配置建议使用标准的 cron 表达式// 使用默认的配置 c := cron.New() // 可以配置如果当前任务正在进行,那么跳过 c := cron.New(cron.WithChain(cron.SkipIfStillRunning(logger))) // 官方也提供了旧版本的秒级的定义,这个注意你需要传入的 cron 表达式不再是标准 cron 表达式 c := cron.New(cron.WithSeconds()) 在上面的代码中出现了一个 logger,我使用的是 logrus,在源码中可以看到 cron 需要的 logger 的定义 // Logger is the interface used in this package for logging, so that any backend // can be plugged in. It is a subset of the github.com/go-logr/logr interface. type Logger interface { // Info logs routine messages about cron's operation. Info(msg string, keysAndValues ...interface{}) // Error logs an error condition. Error(err error, msg string, keysAndValues ...interface{}) } 那么我们定义了一个 Clog 结构体,实现对应的接口就行了 import ( "github.com/robfig/cron/v3" log "github.com/sirupsen/logrus" ) type CLog struct { clog *log.Logger } func (l *CLog) Info(msg string, keysAndValues ...interface{}) { l.clog.WithFields(log.Fields{ "data": keysAndValues, }).Info(msg) } func (l *CLog) Error(err error, msg string, keysAndValues ...interface{}) { l.clog.WithFields(log.Fields{ "msg": msg, "data": keysAndValues, }).Warn(msg) } 添加任务 启动定时任务有两种方法,分别是传入函数和传入任务。 传入函数 我们看到文档中给出的范例,可以看到任务的添加是通过 c.AddFunc() 这个函数来进行的,直接传入一个函数即可,可以看到定义是 func (c *Cron) AddFunc(spec string, cmd func()) (EntryID, error)。 # Runs at 6am in time.Local cron.New().AddFunc("0 6 * * ?", ...) # Runs at 6am in America/New_York nyc, _ := time.LoadLocation("America/New_York") c := cron.New(cron.WithLocation(nyc)) c.AddFunc("0 6 * * ?", ...) // AddFunc adds a func to the Cron to be run on the given schedule. // The spec is parsed using the time zone of this Cron instance as the default. // An opaque ID is returned that can be used to later remove it. func (c *Cron) AddFunc(spec string, cmd func()) (EntryID, error) { return c.AddJob(spec, FuncJob(cmd)) }举个例子,如果你传入的任务仅仅就是一个简单函数进行执行,使用 AddFunc() 就行了,同时也可以通过闭包来引用函数外面的变量,下面是一个完整的例子。package main import ( "fmt" "github.com/robfig/cron/v3" "time" ) func TestCron() { c := cron.New() i := 1 c.AddFunc("*/1 * * * *", func() { fmt.Println("每分钟执行一次", i) i++ }) c.Start() time.Sleep(time.Minute * 5) } func main() { TestCron() } /* output 每分钟执行一次 1 每分钟执行一次 2 每分钟执行一次 3 每分钟执行一次 4 每分钟执行一次 5 */ 传入任务 但是如果我们定义的任务里面还需要留存其他信息呢,可以使用 AddJob() 这个函数,追溯一下源码定义。 // AddJob adds a Job to the Cron to be run on the given schedule. // The spec is parsed using the time zone of this Cron instance as the default. // An opaque ID is returned that can be used to later remove it. func (c *Cron) AddJob(spec string, cmd Job) (EntryID, error) { schedule, err := c.parser.Parse(spec) if err != nil { return 0, err } return c.Schedule(schedule, cmd), nil } // 可以看到需要传入两个参数,`spec` 就是 cron 表达式,Job 类型我们好像还没见过,点进去看 // Job is an interface for submitted cron jobs. type Job interface { Run() } 现在知道我们的定时任务只需要实现 Run() 这个函数就行了,所以我们可以给出自己的 Job 定义 type Job struct { A int `json:"a"` B int `json:"b"` C string `json:"c"` Shut chan int `json:"shut"` } // implement Run() interface to start rsync job func (this Job) Run() { this.A++ fmt.Printf("A: %d\n", this.A) *this.B++ fmt.Printf("B: %d\n", *this.B) *this.C += "str" fmt.Printf("C: %s\n", *this.C) }代码例子给出一个完整代码的示例,我封装了一个 StartJob 函数,方便自己的管理,当然在 c.AddJob() 处可添加多个任务,都会 cron 的要求执行package main import ( "fmt" "github.com/robfig/cron/v3" log "github.com/sirupsen/logrus" "time" ) // 定时任务计划 /* - spec,传入 cron 时间设置 - job,对应执行的任务 */ func StartJob(spec string, job Job) { logger := &CLog{clog: log.New()} logger.clog.SetFormatter(&log.TextFormatter{ FullTimestamp: true, TimestampFormat: "2006-01-02 15:04:05", }) c := cron.New(cron.WithChain(cron.SkipIfStillRunning(logger))) c.AddJob(spec, &job) // 启动执行任务 c.Start() // 退出时关闭计划任务 defer c.Stop() // 如果使用 select{} 那么就一直会循环 select { case <-job.Shut: return } } func StopJob(shut chan int) { shut <- 0 } type CLog struct { clog *log.Logger } func (l *CLog) Info(msg string, keysAndValues ...interface{}) { l.clog.WithFields(log.Fields{ "data": keysAndValues, }).Info(msg) } func (l *CLog) Error(err error, msg string, keysAndValues ...interface{}) { l.clog.WithFields(log.Fields{ "msg": msg, "data": keysAndValues, }).Warn(msg) } type Job struct { A int `json:"a"` B int `json:"b"` C string `json:"c"` Shut chan int `json:"shut"` } // implement Run() interface to start job func (j *Job) Run() { j.A++ fmt.Printf("A: %d\n", j.A) j.B++ fmt.Printf("B: %d\n", j.B) j.C += "str" fmt.Printf("C: %s\n", j.C) } func main() { job1 := Job{ A: 0, B: 1, C: "", Shut: make(chan int, 1), } // 每分钟执行一次 go StartJob("*/1 * * * *", job1) time.Sleep(time.Minute * 3) } /* output A: 1 B: 2 C: str A: 2 B: 3 C: strstr A: 3 B: 4 C: strstrstr */总结这个 cron 库的 v3 版本直接使用标准 cron 表达式即可启动 cron 任务有传入函数和传入任务两种方法,如果需要管理建议实现自己的 Job 类参考资料robfig/crongodoc-croncrontab.guru
2021年07月10日
17 阅读
0 评论
0 点赞
2021-06-21
php调用java类
参考:https://blog.csdn.net/qq_35921925/article/details/108110519http://www.piaoyi.org/php/php-java-bridge-jar-class.html一、centos下 PHP 调用 jar包1.准备工作1.1、php环境【php7.2】,并且将php.ini中的allow_url_include改为On1.2、安装java环境yum install java2.下载 JavaBridge.jar(快捷下载)JavaBridge.jar和Java.inc下载地址: http://php-java-bridge.sourceforge.net/pjb/download.php打一个jar包,将打包好的jar包以及JavaBridge.jar放到ext目录里面cp Hello.jar /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.292.b10-1.el7_9.x86_64/jre/lib/ext cp JavaBridge.jar /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.292.b10-1.el7_9.x86_64/jre/lib/ext cd /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.292.b10-1.el7_9.x86_64/jre/lib/ext启动JavaBridge.jarjava -jar JavaBridge.jar SERVLET:8080 3 JavaBridge.log新建一个php站点,把Java.inc放到根目录,新建index.php,index.php内容如下<?php header( 'Content-Type: text/html; charset=UTF-8' ); define("JAVA_DEBUG", true); //调试设置 define("JAVA_HOSTS", "127.0.0.1:8080"); //设置javabridge监听端口 /*0: Log nothing, not even fatal errors. 1: Log fatal system errors such as "out of memory error". 2: Log java exceptions.*/ define("JAVA_LOG_LEVEL", 2); //java.log_level: 0-6 require_once "Java.inc"; //php调用java的接口,与该脚本位于同一目录 java_set_file_encoding("UTF-8"); //设置JAVA编码。 $ob = new Java("Hello"); //实例 try{ $res = $ob->h('1333'); echo $res; } catch(Exception $e) { var_dump($e); } // 输出 1333【一些注意事项】:关于PHP-Java-Bridge的各种函数使用:1、高版本的java_require不再使用,也无法使用,由于放到java虚拟机下面,则不需要再手动引入包文件。2、java_value()用于获取值,而且必须使用该函数获取值。(特别注意:如果该值需要存入数据库,那么必须使用该java_value函数,不然会报错,或者无法存入数据库)3、java_inspect()对实例化或者方法进行print_r类似的输出。(注:请不要直接使用var_dump这样的输出方法输出java的类、方法、变量,需要使用java_inspect或者java_value,例如:var_dump(java_inspect($abc)))4、实例化使用 $test = new Java("Test")的方式,如果实例化的方法中存在参数,可以这样new Java("Test","pram")提醒:1、务必确保对java.inc的引用,确保引用正确2、务必确保对jar包放在能引用的地方,比如java虚拟机jre下面3、在PHP中调用Java使用PHP的的写法即可
2021年06月21日
58 阅读
0 评论
0 点赞
2021-06-18
gin渲染多层目录下模板
试着学习一下go的gin框架,相比php来说,坑太多了在模板里面如果 不定义define 则相同文件名会被 覆盖 ,必须定义项目结构:layout/header.html文件(1)任何文件要以{{define "layout/header"}} 开始,最后{{end}}结束(2)公共头部 define{{define "layout/header"}} header {{end}} admin/index.html(1)文件要以{{define "admin/index.html"}} 开始,最后{{end}}结束,这里的index可以加文件后缀,index.html(2)需要通过{{template "layout/header" .}} 最后面有个【点】,它的意思是要把当前页面的变量传递到head.html中{{define "admin/index.html"}} {{template "layout/header" .}} admin {{end}}输出模板代码c.HTML(http.StatusOK, "admin/index.html", gin.H{})模板渲染设置r.LoadHTMLGlob("views/**/*")
2021年06月18日
1 阅读
0 评论
0 点赞
2021-05-11
golang实现windows下切换代理
golang实现windows下切换代理实现很简单 主要修改注册表文件 利用walk展示页面界面如下package main import ( "github.com/lxn/walk" . "github.com/lxn/walk/declarative" "github.com/lxn/win" "golang.org/x/sys/windows/registry" "log" ) func main() { var mw *walk.MainWindow var inTE *walk.TextEdit if err := (MainWindow{ AssignTo: &mw, //Icon: "img/logo.ico", Title: "代理", Size: Size{300, 200}, Layout: VBox{}, Children: []Widget{ HSplitter{ Children: []Widget{ TextEdit{AssignTo: &inTE, ReadOnly: true}, }, }, PushButton{ Text: "连接", OnClicked: func() { status, ip := start() if status { inTE.SetText("连接成功\n当前IP" + ip) } else { inTE.SetText("连接失败") } }, }, PushButton{ Text: "关闭", OnClicked: func() { status := editReg("0", "") if status { inTE.SetText("连接已关闭") } else { inTE.SetText("关闭失败") } }, }, }, }.Create()); err != nil { log.Fatal(err) } win.SetWindowLong(mw.Handle(), win.GWL_STYLE, win.GetWindowLong(mw.Handle(), win.GWL_STYLE) & ^win.WS_MAXIMIZEBOX & ^win.WS_THICKFRAME) mw.Run() } func start() (bool, string) { ip, port := getIp() status := editReg("1", ip+":"+port) return status, ip } // 获取ip func getIp() (string, string) { // 自行获取ip return "183.88.226.50", "8080" } func editReg(enable, proxy string) bool { key, exists, err := registry.CreateKey(registry.CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", registry.ALL_ACCESS) if err != nil { log.Fatal(err) } defer key.Close() if !exists { return false } err = key.SetStringValue("ProxyEnable", enable) if err != nil { return false } err = key.SetStringValue("ProxyServer", proxy) if err != nil { return false } return true }
2021年05月11日
22 阅读
0 评论
0 点赞
2021-05-07
分享自己封装的mysql类 基于pdo
分享自己封装的mysql类 基于pdo由于经常开发小型系统用不到框架,用原生写又太麻烦干脆封装一个MySQL操作类用了连贯操作 用法和tp相似 上手快 Db.zip用法 $res = Db::table('tbl_user')->where('id', 1)->find(); // 获取单个数据 $res = Db::table('tbl_user')->order('id', 'desc')->select(); // 获取结果集 排序 $res = Db::instance()->getLastSql(); // 获取上次执行的sql $res = Db::table("tbl_user")->where('id', 2)->update(['name' => '云青']); // 更新数据 $res = Db::table("tbl_user")->insert(['account' => 'acc', 'name' => 123]); // 插入单个数据 并返回插入id $res = Db::table("tbl_user") ->insertAll( [ ['account' => 'test1', 'name' => 'test1'], ['account' => 'test2', 'name' => 'test2'] ] ); // 批量插入数据 $res = Db::table('tbl_user')->where('id', 5)->delete(); // 删除数据 $res = Db::table('tbl_user')->tbFields(); // 获取数据表字段 $res = Db::table('tbl_user')->count('id'); // 统计数据条数 $res = Db::table('tbl_user')->field('id')->sum(); // 统计id和 $res = Db::table('tbl_user')->doSql("select * from tbl_user"); // 自定义sql $res = Db::instance()->startTrans(); // 开启事务 $res = Db::table("tbl_user") ->insertAll( [ ['account' => 'test1', 'name' => 'test1'], ['account' => 'test2', 'test2' => 'test2'] ] ); // 批量插入数据 $res = Db::instance()->commit(); // 提交 $res = Db::instance()->rollback(); // 回滚 $res = Db::table('tbl_user') ->field('id') ->whereIn('account', 'test1,test2') ->where('id', '!=', 2) ->select(); // whereIn $res = Db::table('tbl_user') // whereIn ->field('id') ->whereIn('account', 'test1,test2') ->whereIn('name', ['test1', 'test2'], 'or') ->where('pmid', '=', 0) ->select();封装类<?php /** * @author anderyly * @email admin@aaayun.cc * @link http://vclove.cn/ * @copyright Copyright (c) 2018 */ namespace ay\lib; class Db { private static $db; private $dbType = 'mysql'; private $pConnect = true; private static $table; private $host; private $port; private $dbName; private $user; private $pass; private $group = ''; private static $sql = false; //最后一条sql语句 private $where = ''; private $order = ''; private $limit = ''; private $field = '*'; private $clear = 0; //状态,0表示查询条件干净,1表示查询条件污染 private static $trans = 0; //事务指令数 /** * 初始化 * Dc constructor. * @param null $conf 数据库配置 */ public function __construct($conf = null) { class_exists('PDO') or halt("PDO模块不存在"); if (is_null($conf)) { $conf = C(); } $this->dbType = $conf['DB_TYPE']; $this->host = $conf['DB_HOST']; $this->port = $conf['DB_PORT']; $this->user = $conf['DB_USER']; $this->pass = $conf['DB_PASS']; $this->dbName = $conf['DB_NAME']; //连接数据库 if (is_null(self::$db)) { $this->connect(); } } /** * PDO连接数据库 * @throws \Exception */ private function connect() { $dsn = $this->dbType . ':host=' . $this->host . ';port=' . $this->port . ';dbname=' . $this->dbName; $options = $this->pConnect ? [\PDO::ATTR_PERSISTENT => true] : []; try { $dbh = new \PDO($dsn, $this->user, $this->pass, $options); $dbh->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); $dbh->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false); } catch (\PDOException $e) { throw new \Exception('Connection failed: ' . $e->getMessage()); } $dbh->exec('SET NAMES utf8'); self::$db = $dbh; } /** * @return object */ public static function instance() { return new self(); } /** * 设置数据表名 * @param $table * @return object */ public static function name($table) { if (empty($table)) { halt('不能设置数据表名为空'); } $tableS = C('DB_PRE') . $table; self::$table = self::addChar($tableS); return new self(); } /** * 设置数据表名 * @param $table * @return object */ public static function table($table) { if (empty($table)) { halt('不能设置数据表名为空'); } self::$table = self::addChar($table); return new self(); } /** * 设置当前数据表别名 * @param $alias * @return object */ public function alias($alias): object { if (empty($alias) or empty(self::$table)) { halt('数据库表名设置别名为空'); } self::$table .= ' AS ' . $alias; return $this; } private static function addChar($value, $num = 0) { if (strpos($value, "`") === false and $num == 1 and !is_int($value)) { $data = "'" . trim($value) . "'"; } else if (strpos($value, "`") === false and !is_int($value) and $num != 1) { $data = "`" . trim($value) . "`"; } else { $data = trim($value); } return $data; } /** * 执行查询 主要针对 SELECT, SHOW 等指令 * @param string $sql * @return mixed */ public function doQuery($sql = '', $options = true) { self::$sql = $sql; if ($options) { $result = self::$db->query(self::$sql)->fetchAll(\PDO::FETCH_ASSOC); } else { $result = self::$db->query(self::$sql)->fetch(\PDO::FETCH_ASSOC); } return $result; } /** * 执行语句 针对 INSERT, UPDATE 以及DELETE,exec结果返回受影响的行数 * @param string $sql * @return mixed */ public function doExec($sql = '', $op = '') { self::$sql = $sql; $res = self::$db->exec(self::$sql); if ($op == 'insert') { $res = $this->getLastInsId(); } return $res; } /** * 执行sql语句,自动判断进行查询或者执行操作 * @param string $sql SQL指令 * @return mixed */ public function doSql($sql = '') { $queryIps = 'INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|LOAD DATA|SELECT .* INTO|COPY|ALTER|GRANT|REVOKE|LOCK|UNLOCK'; if (preg_match('/^\s*"?(' . $queryIps . ')\s+/i', $sql)) { return $this->doExec($sql); } else { return $this->doQuery($sql); } } /** * 获取上一次查询的sql * @return string */ public function getLastSql() { return self::$sql; } /** * 插入方法 * @param array $data * @return mixed * @throws \Exception */ public function insert(array $data) { $data = $this->dataFormat($data); if (!$data) { exit('插入数据不能为空'); } $sql = 'INSERT INTO ' . self::$table . '(' . implode(',', array_keys($data)) . ') VALUES(' . implode(',', array_values($data)) . ')'; return $this->doExec($sql, 'insert'); } /** * 批量插入方法 * @param array $data * @return mixed * @throws \Exception */ public function insertAll(array $data) { $value = '('; foreach ($data as $k => $v) { foreach ($v as $k1 => $v1) { $value .= "'" . $v1 . "',"; } $value = rtrim($value, ','); $value .= '), ('; } $value = rtrim($value, ', ('); $sql = 'INSERT INTO ' . self::$table . '(' . implode(',', array_keys($data[0])) . ') VALUES ' . $value; return $this->doExec($sql, false); } /** * 获取最后一次插入时的ID * @return mixed */ public function getLastInsId() { $sql = 'SELECT LAST_INSERT_ID()'; $res = $this->doQuery($sql, false); return isset($res['LAST_INSERT_ID()']) ? $res['LAST_INSERT_ID()'] : 'false'; } /** * 删除方法 * @return mixed * @throws \Exception */ public function delete() { //安全考虑,阻止全表删除 if (!trim($this->where)) { exit('删除条件禁止为空'); } $sql = 'DELETE FROM ' . self::$table . ' ' . $this->where; $this->clear = 1; $this->clear(); return $this->doExec($sql); } /** * 更新方法 * @param array $data * @return mixed|void * @throws \Exception */ public function update(array $data) { //安全考虑,阻止全表更新 if (!trim($this->where)) { exit('更新条件禁止为空'); } $data = $this->dataFormat($data); if (!$data) { return; } $valArr = array(); foreach ($data as $k => $v) { $valArr[] = $k . '=' . $v; } $valStr = implode(',', $valArr); $sql = 'UPDATE ' . trim(self::$table) . ' SET ' . trim($valStr) . ' ' . trim($this->where); return $this->doExec($sql); } /** * 更新语句 字段值加 $number * @param array|string $field * @param null $number * @return mixed|void * @throws \Exception */ public function setInc($field, $number = null) { //安全考虑,阻止全表更新 if (!trim($this->where)) { exit('更新条件禁止为空'); } if (is_array($field)) { $data = $this->dataFormat($field); if (!$data) { return; } $valArr = array(); foreach ($data as $k => $v) { $valArr[] = $k . '=' . $k . '+' . $v; } $valStr = implode(',', $valArr); $sql = 'UPDATE ' . trim(self::$table) . ' SET ' . trim($valStr) . ' ' . trim($this->where); } else if (is_string($field) and is_null($number)) { $sql = 'UPDATE ' . trim(self::$table) . ' SET ' . self::addChar($field) . '=' . self::addChar($field) . '+1 ' . trim($this->where); } else { $sql = 'UPDATE ' . trim(self::$table) . ' SET ' . self::addChar($field) . '=' . self::addChar($field) . '+' . self::addChar($number, 1) . ' ' . trim($this->where); } return $this->doExec($sql); } /** * 更新语句 字段值减 $number * @param array|string $field * @param null $number * @return mixed|void * @throws \Exception */ public function setDec($field, $number = null) { //安全考虑,阻止全表更新 if (!trim($this->where)) { exit('更新条件禁止为空'); } if (is_array($field)) { $data = $this->dataFormat($field); if (!$data) { return; } $valArr = array(); foreach ($data as $k => $v) { $valArr[] = $k . '=' . $k . '-' . $v; } $valStr = implode(',', $valArr); $sql = 'UPDATE ' . trim(self::$table) . ' SET ' . trim($valStr) . ' ' . trim($this->where); } else if (is_string($field) and is_null($number)) { $sql = 'UPDATE ' . trim(self::$table) . ' SET ' . self::addChar($field) . '=' . self::addChar($field) . '-1 ' . trim($this->where); } else { $sql = 'UPDATE ' . trim(self::$table) . ' SET ' . self::addChar($field) . '=' . self::addChar($field) . '-' . self::addChar($number, 1) . ' ' . trim($this->where); } return $this->doExec($sql); } /** * 查询函数 * @return array|boolean 结果集 */ public function select() { $sql = 'SELECT ' . trim($this->field) . ' FROM ' . self::$table . ' ' . trim($this->where) . ' ' . trim($this->order) . ' ' . trim($this->limit) . " " . trim($this->group); $this->clear = 1; $this->clear(); $res = $this->doQuery(trim($sql)); return isset($res[0]) ? $res : []; } /** * 查询函数 * @return array|boolean 结果集 */ public function find() { $sql = "SELECT " . trim($this->field) . " FROM " . self::$table . " " . trim($this->where) . " " . trim($this->order) . " " . trim(" LIMIT 1") . " " . trim($this->group); $this->clear = 1; $this->clear(); return $this->doQuery(trim($sql), false); } /** * 设置条件 * @param string | array $option * @param string $where * @param string $value * @return $this */ public function where($option, $where = null, $value = null) { if ($this->clear > 0) { $this->clear(); } // 判断之前是否使用where语句 if (strpos($this->where, 'WHERE')) { $this->where .= ' AND '; $useWhere = 1; } else { $this->where = ' WHERE '; } // 判断第一个参数为字符 if (is_string($option)) { // 当三个参数都为字符串 if (!is_null($value)): $this->where .= $option . $this->whereTo($where) . $this->addChar($value, 1); endif; // 当第三个参数不存在 if (is_null($value)) { $this->where .= $option . '=' . $this->addChar($where, 1); } else if (is_null($where)) { // 当第二个参数不存在 $this->where .= $option; } } else if (is_array($option)) { // 当第一个参数为数组 $qz = "("; foreach ($option as $v) { // 当第一个参数循环后为数组 if (is_array($v)) { if (strstr($this->where, '(')) { $qz = ' '; } if (isset($useWhere)) { $qz = '('; unset($useWhere); } $condition = $qz . $this->addChar($v[0], 'where') . ' ' . $v[1] . ' ' . $this->addChar($v[2], 1); } else { $this->where .= ' ' . $this->addChar($option[0]) . $option[1] . $option[2]; $cc = 1; break; } $logIc = isset($v[3]) ? ' ' . $v[3] : ' AND'; $this->where .= isset($mark) ? $logIc . $condition : $condition; $mark = 1; } if (!isset($cc)) { $this->where .= ')'; } } return $this; } private function whereTo($field) { switch ($field) { case ($field == 'neq' or $field == '!='): return '!='; case ($field == 'eq' or $field == '='): return '='; case ($field == 'like' or $field == '%'): return 'LIKE'; default: return $field; } } /** * 设置条件 * @param string $option * @param string | array $value * @return $this */ public function whereIn($option, $value, $tj = 'AND') { if ($this->clear > 0) { $this->clear(); } // 判断之前是否使用where语句 if (strpos($this->where, 'WHERE')) { $this->where .= ' ' . $tj . ' '; $useWhere = 1; } else { $this->where = ' WHERE '; } $arr = explode(',', $value); $str = ''; foreach ($arr as $v) { $str .= $this->addChar($v, 1) . ','; } $str = rtrim($str, ','); // 判断第一个参数为字符 if (is_string($value)) { $this->where .= $option . " IN (" . $str . ")"; } else if (is_array($value)) { $str = ''; foreach ($value as $v) { $str .= $this->addChar($v, 1) . ','; } $str = rtrim($str, ','); $this->where .= $option . " IN (" . $str . ")"; } return $this; } /** * 设置条件 * @param $option * @param string $where * @param string $value * @return $this */ public function whereOr($option, $where = null, $value = null) { if ($this->clear > 0) { $this->clear(); } if (strpos($this->where, 'WHERE')) { $this->where .= ' OR '; $ss = 1; } else { $this->where = ' WHERE '; } if (is_string($option)) { if (!is_null($value)): $this->where .= $option . $this->whereTo($where) . $this->addChar($value, 1); endif; if (is_null($value)) { $this->where .= $option . '=' . $this->addChar($where, 1); } else if (is_null($where)) { $this->where .= $option; } } else if (is_array($option)) { $qz = '('; foreach ($option as $v) { $logIc = ' AND'; if (is_array($v)) { if (strstr($this->where, '(')) { $qz = ' '; } if (isset($ss)) { $qz = '('; unset($ss); } $condition = $qz . $this->addChar($v[0]) . ' ' . $v[1] . ' ' . $this->addChar($v[2], 1); } else { $this->where .= ' ' . $this->addChar($option[0]) . $option[1] . $option[2]; $cc = 1; break; } if (isset($v[3]) and ($v[3] == 'or' or $v[3] == 'OR')) { $logIc = ' OR'; $this->where .= isset($mark) ? $logIc . $condition : $condition; } else { $this->where .= isset($mark) ? $logIc . $condition : $condition; } $mark = 1; } if (!isset($cc)) { $this->where .= ')'; } } return $this; } /** * 取得数据表的字段信息 * @return array */ public function tbFields() { $sql = 'SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME="' . str_replace('`', '', self::$table) . '" AND TABLE_SCHEMA="' . $this->dbName . '"'; $res = $this->doQuery($sql); $ret = array(); foreach ($res as $key => $value) { $ret[] = $value['COLUMN_NAME']; } return $ret; } /** * 过滤并格式化数据表字段 * @param $data * @return array */ public function dataFormat($data) { if (!is_array($data)) { return []; } $table_column = $this->tbFields(); $ret = []; foreach ($data as $key => $val): if (!is_scalar($val)) { continue; } if (array_key_exists($key, $table_column)): $key = $this->addChar($key); if (is_int($val)) { $val = intval($val); } else if (is_float($val)) { $val = floatval($val); } else if (preg_match('/^\(\w*(\+|\-|\*|\/)?\w*\)$/i', $val)) { $val = $val; } elseif (is_string($val)) { $val = '"' . addslashes($val) . '"'; } $ret[$key] = $val; endif; endforeach; return $ret; } /** * 排序 * @param $option * @param null $sort * @return $this */ public function order($option, $sort = null) { if ($this->clear > 0) { $this->clear(); } $this->order = ' ORDER BY '; if (!is_null($sort)) { $this->order .= $option . ' ' . $sort; } else if (is_string($option)) { $this->order .= $option; } else if (is_array($option)) { foreach ($option as $k => $v) { $order = $k . " " . $v; $this->order .= isset($mark) ? ',' . $order : $order; $mark = 1; } } return $this; } /** * @param $option * @return $this */ public function group($option) { if ($this->clear > 0) { $this->clear(); } $this->group = ' GROUP BY ' . $option; return $this; } /** * 分页 * @param $page * @param null $pageSize * @return $this */ public function limit($page, $pageSize = null) { if ($this->clear > 0) { $this->clear(); } if ($pageSize === null) { $this->limit = 'LIMIT ' . $page; } else { $pagEval = intval(($page - 1) * $pageSize); $this->limit = 'LIMIT ' . $pagEval . ',' . $pageSize; } return $this; } /** * 设置字段名 * @param $field * @return $this */ public function field($field) { if ($this->clear > 0) { $this->clear(); } $this->field = $field; return $this; } /** * 查询 左右内全 * @param $tab * @param string $where * @param string $join * @return $this */ public function join($tab, $where = '', $join = 'INNER') { if ($this->clear > 0) { $this->clear(); } if (is_array($tab)) { foreach ($tab as $k => $v): $table = $k . ' AS ' . $v; endforeach; } else { $table = str_replace(' ', ' AS ', $tab); } self::$table .= ' ' . $join . ' JOIN ' . $table . ' ON(' . $where . ')'; return $this; } /** * 计数 * @return mixed */ public function count() { if ($this->clear > 0) { $this->clear(); } $sql = 'SELECT count(' . trim($this->field) . ') AS ' . trim($this->field) . ' FROM ' . self::$table . ' ' . trim($this->where) . " " . trim($this->order); $rows = $this->doQuery($sql, false); return $rows[trim($this->field)]; } /** * 统计 * @return mixed */ public function sum() { if ($this->clear > 0) { $this->clear(); } $sql = 'SELECT SUM(' . trim($this->field) . ') AS ' . trim($this->field) . ' FROM ' . self::$table . ' ' . trim($this->where) . " " . trim($this->order); $rows = $this->doQuery($sql, false); return $rows[trim($this->field)]; } /** * 清理标记函数 */ private function clear() { $this->where = ''; $this->order = ''; $this->limit = ''; $this->field = '*'; $this->clear = 0; } /** * 手动清理标记 * @return $this */ public function clearKey() { $this->clear(); return $this; } /** * 启动事务 */ public function startTrans() { //数据rollback 支持 if (self::$trans == 0) { self::$db->beginTransaction(); } self::$trans++; return; } /** * 用于非自动提交状态下面的查询提交 * @return bool */ public function commit() { $result = true; if (self::$trans > 0) { $result = self::$db->commit(); self::$trans = 0; } return $result; } /** * 事务回滚 * @return bool */ public function rollback() { $result = true; if (self::$trans > 0) { $result = self::$db->rollback(); self::$trans = 0; } return $result; } /** * 关闭连接 */ public function close() { if (!is_null(self::$db)) { self::$db = null; } } }
2021年05月07日
20 阅读
1 评论
0 点赞
1
...
4
5
6
...
19