* [ ] CurdTrait.php
* [ ] 功能
* 简单的封装CURD操作,在项目里面操作数据库表的 Model 层里面 use CurdTrait
* 把常用的功能简单封装,方便维护,当底层框架 mysql 操作类方法改变的时候,只需要修改该文件即可
* 文件路径:/home/wwwroot/project/application/lib/model/Common/CurdTrait.php
~~~
<?php
namespace model\Common;
/**
* Trait CurdTrait
* 针对数据库的 CURD 操作,增、删、改、查
* 用法:在需要的 Model 中 use CurdTrait;
* 并且这个 Model 中必须定义静态成员变量:
* 假设 model 文件为 UserModel
* 如果在 UserModel 中定义的成员变量 $tabName 为空,那么该 trait 会自动获取当前类名,去截取到 user 表名
* 同理 UserLogModel,如果定义的成员变量 $tabName 为空,那么该 trait 会自动获取当前类名,去截取到 user_log 表名
* 例如:
* protected static $dbObj = 'Admin'; //操作的数据库
* protected static $tabName = 'admin'; //操作的表名
* protected static $tabId = 'id'; //[如果没有,就不需要定义] 该表的主键
* @package model\Common
* @author YoY
*/
trait CurdTrait
{
//当前model操作的表对象
protected static $tabObj = false;
/**
* 下划线转驼峰
* @param string $str
* @return string|string[]|null
* @author YoY
*/
public static function lineToHump($str = '')
{
if (empty($str)) {
return '';
}
$str = preg_replace_callback('/([-_]+([a-z]{1}))/i', function ($matches) {
return strtoupper($matches[2]);
}, $str);
return empty($str) ? '' : $str;
}
/**
* 驼峰转下划线
* @param string $str
* @return string|string[]|null
* @author YoY
*/
public static function humpToLine($str = '')
{
if (empty($str)) {
return '';
}
$str = preg_replace_callback('/([A-Z]{1})/', function ($matches) {
return '_' . strtolower($matches[0]);
}, $str);
$str = ltrim($str, '_');
return empty($str) ? '' : $str;
}
/**
* 记录允许日志,比如允许中遇到的异常
* @param $message
* @return bool
* @author YoY
*/
public static function runLog($message)
{
try {
//如果 seaslog 拓展没有安装,就不记录异常日志了
if (!extension_loaded('seaslog')) {
return false;
}
if (is_array($message) || is_object($message)) {
$message = json_encode($message, JSON_UNESCAPED_UNICODE);
}
return \SeasLog::info($message);
} catch (\Exception $e) {
return false;
}
}
/**
* 获取操作的表名
* @return string
* @author YoY
*/
public static function getTabName()
{
// 如果定义的操作的表名为空,默认根据当前类文件名称去截取 TaskModel 自动找到task表名
if (empty(self::$tabName)) {
$_class_ = explode('\\', __CLASS__);
$key = count($_class_) - 1;
$_class_ = self::humpToLine($_class_[$key]);
$_class_ = explode('_', $_class_);
$key = count($_class_) - 1;
if ($key > 0) unset($_class_[$key]);
self::$tabName = implode('_', $_class_);
}
return self::$tabName;
}
/**
* 获取表主键
* @return string
* @author YoY
*/
public static function getTabId()
{
// 默认主键
if (!isset(self::$tabId)) self::$tabId = 'id';
return self::$tabId;
}
/**
* 获取操作表对象
* @return bool
* @throws \Exception
* @author YoY
*/
public static function getTabOBJ()
{
if (!isset(self::$dbObj)) throw new \Exception('操作表数据库对象 self::$dbObj 未定义');
self::getTabName();
if (!isset(self::$tabName)) throw new \Exception('操作表名 self::$tabName 未定义');
if (empty(self::$tabObj) || !is_object(self::$tabObj) || empty(self::$tabObj->MyData['table'])) {
$dbObj = '\\mysql\\' . self::$dbObj; //拼接操作表对象的静态类
self::$tabObj = $dbObj::table(self::$tabName);
}
return self::$tabObj;
}
/**
* 添加记录
* 例如:user表新增一条记录 name = YoY pwd = 123456 的记录到表中
* 返回添加成功的主键:UserModel::add( ['name' => 'YoY', 'pwd' => 123456] );
* 返回添加成功的影响行数:UserModel::add( ['name' => 'YoY', 'pwd' => 123456], 'row' );
* 如果只是需要返回sql语句:UserModel::add( ['name' => 'YoY', 'pwd' => 123456], 'demo' );
* @param array $data [要新增的数据]
* @param string $get_sql [返回的形式]
* @return bool
* @author YoY
*/
public static function add($data = [], $get_sql = '')
{
if (empty($data) || !is_array($data)) {
return false;
}
try {
// 如果没有定义主键,那么就只能返回影响的行数
if (!isset(self::$tabId) && empty($get_sql)) $get_sql = 'row';
return self::getTabOBJ()->data($data)->insert($get_sql);
} catch (\Exception $e) {
// 记录异常日志
self::runLog($e->getMessage());
return false;
}
}
/**
* 批量添加记录
* 例如:user表批量添加记录 name = 1, pwd = 123 和 name = 2, pwd = 321 的记录
* 用法1:UserModel::addAll( [ ['name'=>1, 'pwd' => 123], [ 'name' => 2, 'pwd' => 321] ] );
* 需要返回sql语句:UserModel::addAll( [ ['name'=>1, 'pwd' => 123], [ 'name' => 2, 'pwd' => 321] ], 'demo' );
* @param array $data
* @param string $get_sql
* @return bool
* @author YoY
*/
public static function addAll($data = [], $get_sql = '')
{
if (empty($data)) {
return false;
}
if (empty(self::$tabId) && empty($get_sql)) {
$get_sql = 'row';
}
try {
return self::getTabOBJ()->data($data)->add($get_sql);
} catch (\Exception $e) {
// 记录异常日志
self::runLog($e->getMessage());
return false;
}
}
/**
* 删除记录
* 例如:user表删除一个id为1的记录
* 用法1:UserModel::delete( 1 );
* 用法2:UserModel::delete( '1' );
* 用法3:UserModel::delete( ['id' => 1] );
* 用法4:UserModel::delete( ['id' => '1'] );
* 如果只是返回sql语句:UserModel::delete( ['id' => 1], 'demo' );
* @param array $where [删除记录的where条件]
* @param string $get_sql [是否只返回sql语句,如果写入demo,就是返回sql语句]
* @return bool
* @author YoY
*/
public static function delete($where = [], $get_sql = '')
{
if (!is_array($where) && !is_string($where) && !is_int($where)) {
return false;
}
if (is_array($where) && empty($where)) {
return false;
}
if (is_string($where) && empty($where) && $where !== '0') {
return false;
}
// 不是一个数组,那么就是想通过主键去删除
if (!is_array($where)) {
$where = intval($where);
// 如果不存在主键定义,或者定义了却为空,就返回失败
if (empty(self::getTabId())) {
return false;
}
// 存在主键定义,就自动组装主键的where条件
$where = [self::getTabId() => $where];
}
try {
return self::getTabOBJ()->where($where)->delete($get_sql);
} catch (\Exception $e) {
// 记录异常日志
self::runLog($e->getMessage());
return false;
}
}
/**
* 修改记录
* 例如:user表修改id字段为1的记录中的name为new name
* 用法1:UserMode::save( 1, ['name' => 'new name'] );
* 用法2:UserModel::save( '1', ['name' => 'new name'] );
* 用法3:UserModel::save( ['id' => 1], ['name' => 'new name'] );
* 用法4:UserModel::save( ['id' => '1'], ['name' => 'new name'] );
* 用法5:UserModel::save( ['id' => 1, 'name' => 'new name'] );
* 用法6:UserModel::save( ['id' => '1', 'name' => 'new name'] );
* 如果只是返回sql语句:UserModel::save( ['id' => 1], ['name' => 'new name'], 'demo' );
* @param array $where [要修改的where条件 ]
* @param array $data [要修改新的数据值]
* @param string $get_sql [是否只返回sql语句,如果写入demo,就是返回sql语句]
* @return bool
* @author YoY
*/
public static function save($where = [], $data = [], $get_sql = '')
{
if (!is_array($where) && !is_string($where) && !is_int($where)) {
return false;
}
if (is_array($where) && empty($where)) {
return false;
}
if (is_string($where) && empty($where) && $where !== '0') {
return false;
}
if (!is_array($where)) {
// 如果传入的where条件是以主键,那么就组装主键条件
// 对应使用场景: $tabObj->save( 1, ['name'=>'new name'] );
// 对应使用场景: $tabObj->save( '0', ['name'=>'new name'] );
// 防止有些表的主键是有0存在的时候
$where = intval($where);
if (empty(self::getTabId())) {
return false;
}
$where = [self::getTabId() => $where];
} else {
// 如果传入的是where条件,且where条件中含有主键,并且data是空
// 对应使用场景: $tabObj->save( ['id'=>1,'name'=>'new name'] );
if (is_array($where) && empty($data)) {
// 如果是想按照主键来更新,但是又没有定义主键名称或者定义的主键名称为空
if (empty(self::getTabId())) {
return false;
}
// 然后更新的数据里面,主键字段不存在
if (!isset($where[self::getTabId()])) {
return false;
}
$data = $where;
$where = [self::getTabId() => $where[self::getTabId()]];
unset($data[self::getTabId()]);
}
}
// 防止where条件或更新的数据都为空
if (empty($where) || empty($data)) {
return false;
}
try {
return self::getTabOBJ()->where($where)->data($data)->update($get_sql);
} catch (\Exception $e) {
// 记录异常日志
self::runLog($e->getMessage());
return false;
}
}
/**
* 根据where条件查询单条数据
* 例如:user表获取一条ID为1的记录的name、pwd字段的值
* 用法1:UserModel::find( 1, 'name,pwd' );
* 用法2:UserModel::find( '1', 'name,pwd' );
* 用法3:UserModel::find( ['id' => 1], 'name,pwd' );
* 用法4:UserModel::find( ['id' => '1'], 'name,pwd' );
* 如果只是返回sql语句:$tabObj->find( ['id' => '1'], 'name,pwd', [], 'demo' );
* @param array $where
* @param string $field
* @param $other array [ 其他属性, 比如排序order]
* @param string $get_sql [是否只返回sql语句,如果写入demo,就是返回sql语句]
* @return array
* @author YoY
*/
public static function find($where = [], $field = '', $other = [], $get_sql = '')
{
if (!is_string($field)) {
return [];
}
// 排序规则
$order = $other['order'] ?? '';
$order = self::data_format_order($order);
// 如果where条件不是数组,那么就是想通过主键来查询
if (!is_array($where)) {
// 想通过主键查询,可是又没有设置主键名称,那么就返回空数组
if (empty(self::getTabId())) {
return [];
}
// 主键查询
$where = [self::getTabId() => intval($where)];
}
try {
return self::getTabOBJ()->where($where)->field($field)->order($order)->find($get_sql);
} catch (\Exception $e) {
// 记录异常日志
self::runLog($e->getMessage());
return [];
}
}
/**
* 根据where条件查询数据
* 例如:user表获取 state 为 1的 所有记录,只要字段 id,name,pwd,state,并且按照 id降序,state降序
* 用法1:UserModel::select( ['state' => 1], 'id,name,pwd,state','id DESC,state DESC')
* 用法2:UserModel::select( ['state' => 1], 'id,name,pwd,state','id DESC,state DESC')
* @param array $where [查询的where条件]
* @param string $field
* @param string $order
* @param array $other [ 这个是其他附加属性,比如限制查询的条数,limit,默认limit是查询所有]
* @param string $get_sql [是否只返回sql语句,如果写入demo,就是返回sql语句]
* @return array
* @author YoY
*/
public static function select($where = [], $field = '', $order = '', $other = [], $get_sql = '')
{
// 如果排序为空,默认以主键降序来排序
if (empty($order)) {
$order = empty(self::getTabId()) ? '' : self::getTabId() . ' DESC';
}
// 如果排序为数组,那么需要拼接为字符串 ['id' => 'DESC', 'state' => 'ASC'] 转为 'id DESC,state ASC'
$order = self::data_format_order($order);
// 限制数量
$limit = $other['limit'] ?? 'all';
// 分组
$group = $other['group'] ?? '';
//针对字段查询的时候,可能需要某个字段作为数组的key返回
$fieldBox = explode('|', $field);
$field_key = '';
if (count($fieldBox) > 1) {
$field = $fieldBox[0];
$field_key = $fieldBox[1];
}
try {
$tabObj = self::getTabOBJ()->where($where)->order($order)->field($field, $field_key);
// 判断是否为查询所有,如果不是查询所有,那么就增加一个连贯操作limit,限制查询的数量
if ($limit !== 'all') {
$tabObj = $tabObj->limit($limit);
}
if (!empty($group)) {
$tabObj = $tabObj->group($group);
}
return $tabObj->select($get_sql);
} catch (\Exception $e) {
// 记录异常日志
self::runLog($e->getMessage());
print_r($e->getMessage());
return [];
}
}
/**
* 分页查询数据
* @param int $page [ 页码 ]
* @param int $num [ 每页总条数 ]
* @param array $other [ 其他属性,比如 查询条件where(array), 排序order(array or string), 返回字段field(string) ]
* @return array
* @author YoY
*/
public static function getPage($page = 1, $num = 50, $other = [])
{
$where = $other['where'] ?? [];
$order = $other['order'] ?? '';
$field = $other['field'] ?? '';
// 整理排序
$order = self::data_format_order($order);
try {
$data = self::getTabOBJ()->where($where)->order($order)->field($field)->page($num, $page);
} catch (\Exception $e) {
$data = array(
'page' => array(
'total' => 0,
'pages' => 0,
'top' => 0,
'next' => 0,
'page' => $page,
'count' => $num,
'head' => 0,
),
'list' => [],
);
}
return $data;
}
/**
* 统计数量
* @param $where
* @param string $field
* @param array $other
* @return int
*/
public static function count( $where, $field = '*', $other = [])
{
$mode = $other['mode'] ?? '';
$type = $other['type'] ?? '';
$come = $other['come'] ?? '';
try{
return self::getTabOBJ()->where($where)->count($field, $mode, $type, $come);
}catch ( \Exception $e ){
return 0;
}
}
/**
* 整理排序
* @param string $order
* @return string
* @author YoY
*/
protected static function data_format_order($order = '')
{
if (!empty($order) && is_array($order)) {
$tmp_order = [];
//如果是数组,组装为字符串
foreach ($order as $field_name => $field_val) $tmp_order[] = $field_name . ' ' . $field_val;
$order = implode(',', $tmp_order);
}
return $order;
}
/**
* 复制表结构
* @param $table
* @param string $newtable
* @return bool
*/
public static function creste($table, $newtable = '')
{
try{
$dbObj = '\\mysql\\' . self::$dbObj;
return $dbObj::creste($table, $newtable);
} catch ( \Exception $e ) {
return false;
}
}
/**
* 开始事务
* @return bool
*/
public static function beg()
{
try {
$dbObj = '\\mysql\\' . self::$dbObj;
$dbObj::beg();
return true;
} catch (\Exception $e) {
return false;
}
}
/**
* 提交事务
* @return bool
*/
public static function com()
{
try {
$dbObj = '\\mysql\\' . self::$dbObj;
$dbObj::com();
return true;
} catch (\Exception $e) {
return false;
}
}
/**
* 事务回滚
* @return bool
*/
public static function rol()
{
try {
$dbObj = '\\mysql\\' . self::$dbObj;
$dbObj::rol();
return true;
} catch (\Exception $e) {
return false;
}
}
/**
* 获取操作的类对象
* @return string
*/
protected static function getDbOBJ()
{
//拼接操作表对象的静态类
return '\\mysql\\'.self::$dbObj;
}
/**
* 判断数据库的某个表是否存在
* @param $table
* @return bool
*/
public static function mysql_if_table($table)
{
try {
return (self::getDbOBJ())::mysql_if_table($table);
} catch ( \Exception $e ) {
return false;
}
}
/**
* @param $data
* @param string $field
* @return bool
*/
protected static function tabname($data, $field = '')
{
try {
return (self::getDbOBJ())::tabname($data, $field);
} catch ( \Exception $e ) {
return false;
}
}
/**
* 联合表
* @param $data
* @param bool $type
* @return bool
*/
protected static function union($data, $type = false)
{
try {
return (self::getDbOBJ())::union($data, $type);
} catch ( \Exception $e ) {
return false;
}
}
}
~~~
- 开始使用
- 配置文件
- 路由模式
- AutoLoad类
- 启动文件
- __construct
- SetRouting
- SetAlias
- SetStop
- SetError
- Access
- SetWorker
- SetClassFile
- SetClassDir
- Run
- OpenLoad
- LinuxStartAll
- Session类
- 使用说明
- set
- get
- delete
- pull
- has
- id
- Cookie类
- 使用说明
- set
- get
- delete
- pull
- has
- TempLets类
- 模板语法
- 模板标签
- html
- show
- assign
- obtain
- Request类
- get
- post
- host
- referer
- getip
- localip
- header
- body
- file
- scheme
- protocolversion
- uri
- path
- querystring
- method
- Response
- SendFile
- FileStream
- SendData
- SetStatus
- SetHead
- SetMime
- WebSend
- redirect
- dumpJson
- dump
- come
- ps
- Frame类
- GetWeb
- ViewFile
- RoutingData
- SetClassFile
- SetClassDir
- GetMime
- FileMime
- LoadDir
- StartDir
- IsJson
- ArrJson
- JsonFormat
- ObStart
- GetConfig
- ConfigDir
- TempDir
- GetRunData
- GetStatic
- IsDebug
- SetDebug
- GetDebugInfo
- GlobalVariables类
- 使用说明
- set
- get
- delete
- pull
- has
- id
- Mysql类
- 新版本
- 第三方
- Thinkorm
- Medoo
- 旧版本
- Mysql 配置格式
- 项目中操作数据库
- 项目场景
- 项目数据库配置
- 项目数据库中间类
- 项目中操作数据表
- 连贯操作
- where
- table
- data
- order
- field
- limit
- page
- group
- having
- join
- tabname
- union
- sql
- link
- link_base
- lock
- CURD 操作
- 写入数据
- 数据删除
- 数据查询
- 数据更新
- 数据统计操作
- count
- sum
- max
- min
- avg
- 操作DEMO
- CurdTrait.php
- 项目Model层操作表.md
- Curl类
- Method类
- SslAes类
- layui_zqadmin