内核更新
This commit is contained in:
@@ -41,7 +41,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
||||
{
|
||||
|
||||
// 数据库对象池
|
||||
private static $links = [];
|
||||
protected static $links = [];
|
||||
// 数据库配置
|
||||
protected $connection = [];
|
||||
// 当前模型名称
|
||||
@@ -85,8 +85,6 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
||||
protected $createTime = 'create_time';
|
||||
// 更新时间字段
|
||||
protected $updateTime = 'update_time';
|
||||
// 删除时间字段
|
||||
protected $deleteTime = 'delete_time';
|
||||
// 时间字段取出后的默认时间格式
|
||||
protected $dateFormat = 'Y-m-d H:i:s';
|
||||
// 字段类型或者格式转换
|
||||
@@ -168,10 +166,6 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
||||
$query->pk($this->pk);
|
||||
}
|
||||
|
||||
// 全局作用域
|
||||
if (method_exists($this, 'base')) {
|
||||
call_user_func_array([$this, 'base'], [ & $query]);
|
||||
}
|
||||
self::$links[$model] = $query;
|
||||
}
|
||||
// 返回当前模型的数据库查询对象
|
||||
@@ -275,27 +269,9 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
||||
*/
|
||||
public function setAttr($name, $value, $data = [])
|
||||
{
|
||||
if (is_null($value) && $this->autoWriteTimestamp && in_array($name, [$this->createTime, $this->updateTime, $this->deleteTime])) {
|
||||
if (is_null($value) && $this->autoWriteTimestamp && in_array($name, [$this->createTime, $this->updateTime])) {
|
||||
// 自动写入的时间戳字段
|
||||
if (isset($this->type[$name])) {
|
||||
$type = $this->type[$name];
|
||||
if (strpos($type, ':')) {
|
||||
list($type, $param) = explode(':', $type, 2);
|
||||
}
|
||||
switch ($type) {
|
||||
case 'datetime':
|
||||
$format = !empty($param) ? $param : $this->dateFormat;
|
||||
$value = date($format, $_SERVER['REQUEST_TIME']);
|
||||
break;
|
||||
case 'timestamp':
|
||||
$value = $_SERVER['REQUEST_TIME'];
|
||||
break;
|
||||
}
|
||||
} elseif (is_string($this->autoWriteTimestamp) && in_array(strtolower($this->autoWriteTimestamp), ['datetime', 'date', 'timestamp'])) {
|
||||
$value = date($this->dateFormat, $_SERVER['REQUEST_TIME']);
|
||||
} else {
|
||||
$value = $_SERVER['REQUEST_TIME'];
|
||||
}
|
||||
$value = $this->autoWriteTimestamp($name);
|
||||
} else {
|
||||
// 检测修改器
|
||||
$method = 'set' . Loader::parseName($name, 1) . 'Attr';
|
||||
@@ -316,6 +292,36 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动写入时间戳
|
||||
* @access public
|
||||
* @param string $name 时间戳字段
|
||||
* @return mixed
|
||||
*/
|
||||
protected function autoWriteTimestamp($name)
|
||||
{
|
||||
if (isset($this->type[$name])) {
|
||||
$type = $this->type[$name];
|
||||
if (strpos($type, ':')) {
|
||||
list($type, $param) = explode(':', $type, 2);
|
||||
}
|
||||
switch ($type) {
|
||||
case 'datetime':
|
||||
$format = !empty($param) ? $param : $this->dateFormat;
|
||||
$value = date($format, $_SERVER['REQUEST_TIME']);
|
||||
break;
|
||||
case 'timestamp':
|
||||
$value = $_SERVER['REQUEST_TIME'];
|
||||
break;
|
||||
}
|
||||
} elseif (is_string($this->autoWriteTimestamp) && in_array(strtolower($this->autoWriteTimestamp), ['datetime', 'date', 'timestamp'])) {
|
||||
$value = date($this->dateFormat, $_SERVER['REQUEST_TIME']);
|
||||
} else {
|
||||
$value = $_SERVER['REQUEST_TIME'];
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据写入 类型转换
|
||||
* @access public
|
||||
@@ -777,9 +783,10 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
||||
/**
|
||||
* 删除当前的记录
|
||||
* @access public
|
||||
* @param bool $force 是否强制删除
|
||||
* @return integer
|
||||
*/
|
||||
public function delete()
|
||||
public function delete($force = false)
|
||||
{
|
||||
if (false === $this->trigger('before_delete', $this)) {
|
||||
return false;
|
||||
@@ -960,7 +967,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
||||
*/
|
||||
public static function get($data = null, $with = [], $cache = false)
|
||||
{
|
||||
$query = self::parseQuery($data, $with, $cache);
|
||||
$query = static::parseQuery($data, $with, $cache);
|
||||
return $query->find($data);
|
||||
}
|
||||
|
||||
@@ -975,7 +982,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
||||
*/
|
||||
public static function all($data = null, $with = [], $cache = false)
|
||||
{
|
||||
$query = self::parseQuery($data, $with, $cache);
|
||||
$query = static::parseQuery($data, $with, $cache);
|
||||
return $query->select($data);
|
||||
}
|
||||
|
||||
@@ -1279,14 +1286,19 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
||||
|
||||
public function __call($method, $args)
|
||||
{
|
||||
$query = $this->db();
|
||||
// 全局作用域
|
||||
if (method_exists($this, 'base')) {
|
||||
call_user_func_array('static::base', [ & $query]);
|
||||
}
|
||||
if (method_exists($this, 'scope' . $method)) {
|
||||
// 动态调用命名范围
|
||||
$method = 'scope' . $method;
|
||||
array_unshift($args, $this->db());
|
||||
array_unshift($args, $query);
|
||||
call_user_func_array([$this, $method], $args);
|
||||
return $this;
|
||||
} else {
|
||||
return call_user_func_array([$this->db(), $method], $args);
|
||||
return call_user_func_array([$query, $method], $args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1297,6 +1309,10 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
||||
self::$links[$model] = (new static())->db();
|
||||
}
|
||||
$query = self::$links[$model];
|
||||
// 全局作用域
|
||||
if (method_exists($model, 'base')) {
|
||||
call_user_func_array('static::base', [ & $query]);
|
||||
}
|
||||
return call_user_func_array([$query, $method], $params);
|
||||
}
|
||||
|
||||
|
||||
@@ -1204,9 +1204,9 @@ class Route
|
||||
foreach ($matches[1] as $name) {
|
||||
if (strpos($name, '?')) {
|
||||
$name = substr($name, 0, -1);
|
||||
$replace[] = '(' . (isset($pattern[$name]) ? $pattern[$name] : '') . '?)';
|
||||
$replace[] = '(' . (isset($pattern[$name]) ? $pattern[$name] : '\w+') . '?)';
|
||||
} else {
|
||||
$replace[] = '(' . (isset($pattern[$name]) ? $pattern[$name] : '') . ')';
|
||||
$replace[] = '(' . (isset($pattern[$name]) ? $pattern[$name] : '\w+') . ')';
|
||||
}
|
||||
$value[] = $name;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,9 @@ use think\Route;
|
||||
|
||||
class Url
|
||||
{
|
||||
// 生成URL地址的root
|
||||
protected static $root;
|
||||
|
||||
/**
|
||||
* URL生成 支持路由反射
|
||||
* @param string $url URL表达式,
|
||||
@@ -129,7 +132,7 @@ class Url
|
||||
// 检测域名
|
||||
$domain = self::parseDomain($url, $domain);
|
||||
// URL组装
|
||||
$url = $domain . Request::instance()->root() . '/' . ltrim($url, '/');
|
||||
$url = $domain . (self::$root ?: Request::instance()->root()) . '/' . ltrim($url, '/');
|
||||
return $url;
|
||||
}
|
||||
|
||||
@@ -354,4 +357,11 @@ class Url
|
||||
{
|
||||
Cache::rm('think_route_map');
|
||||
}
|
||||
}
|
||||
|
||||
// 指定当前生成URL地址的root
|
||||
public static function root($root)
|
||||
{
|
||||
self::$root = $root;
|
||||
Request::instance()->root($root);
|
||||
}
|
||||
}
|
||||
|
||||
10
core/library/think/cache/driver/Memcache.php
vendored
10
core/library/think/cache/driver/Memcache.php
vendored
@@ -109,6 +109,7 @@ class Memcache
|
||||
*/
|
||||
public function inc($name, $step = 1)
|
||||
{
|
||||
$name = $this->options['prefix'] . $name;
|
||||
return $this->handler->increment($name, $step);
|
||||
}
|
||||
|
||||
@@ -121,7 +122,14 @@ class Memcache
|
||||
*/
|
||||
public function dec($name, $step = 1)
|
||||
{
|
||||
return $this->handler->decrement($name, $step);
|
||||
$name = $this->options['prefix'] . $name;
|
||||
$value = $this->handler->get($name) - $step;
|
||||
$res = $this->handler->set($name, $value);
|
||||
if (!$res) {
|
||||
return false;
|
||||
} else {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
10
core/library/think/cache/driver/Memcached.php
vendored
10
core/library/think/cache/driver/Memcached.php
vendored
@@ -115,6 +115,7 @@ class Memcached
|
||||
*/
|
||||
public function inc($name, $step = 1)
|
||||
{
|
||||
$name = $this->options['prefix'] . $name;
|
||||
return $this->handler->increment($name, $step);
|
||||
}
|
||||
|
||||
@@ -127,7 +128,14 @@ class Memcached
|
||||
*/
|
||||
public function dec($name, $step = 1)
|
||||
{
|
||||
return $this->handler->decrement($name, $step);
|
||||
$name = $this->options['prefix'] . $name;
|
||||
$value = $this->handler->get($name) - $step;
|
||||
$res = $this->handler->set($name, $value);
|
||||
if (!$res) {
|
||||
return false;
|
||||
} else {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
2
core/library/think/cache/driver/Redis.php
vendored
2
core/library/think/cache/driver/Redis.php
vendored
@@ -115,6 +115,7 @@ class Redis
|
||||
*/
|
||||
public function inc($name, $step = 1)
|
||||
{
|
||||
$name = $this->options['prefix'] . $name;
|
||||
return $this->handler->incrby($name, $step);
|
||||
}
|
||||
|
||||
@@ -127,6 +128,7 @@ class Redis
|
||||
*/
|
||||
public function dec($name, $step = 1)
|
||||
{
|
||||
$name = $this->options['prefix'] . $name;
|
||||
return $this->handler->decrby($name, $step);
|
||||
}
|
||||
|
||||
|
||||
2
core/library/think/cache/driver/Wincache.php
vendored
2
core/library/think/cache/driver/Wincache.php
vendored
@@ -94,6 +94,7 @@ class Wincache
|
||||
*/
|
||||
public function inc($name, $step = 1)
|
||||
{
|
||||
$name = $this->options['prefix'] . $name;
|
||||
return wincache_ucache_inc($name, $step);
|
||||
}
|
||||
|
||||
@@ -106,6 +107,7 @@ class Wincache
|
||||
*/
|
||||
public function dec($name, $step = 1)
|
||||
{
|
||||
$name = $this->options['prefix'] . $name;
|
||||
return wincache_ucache_dec($name, $step);
|
||||
}
|
||||
|
||||
|
||||
2
core/library/think/cache/driver/Xcache.php
vendored
2
core/library/think/cache/driver/Xcache.php
vendored
@@ -94,6 +94,7 @@ class Xcache
|
||||
*/
|
||||
public function inc($name, $step = 1)
|
||||
{
|
||||
$name = $this->options['prefix'] . $name;
|
||||
return xcache_inc($name, $step);
|
||||
}
|
||||
|
||||
@@ -106,6 +107,7 @@ class Xcache
|
||||
*/
|
||||
public function dec($name, $step = 1)
|
||||
{
|
||||
$name = $this->options['prefix'] . $name;
|
||||
return xcache_dec($name, $step);
|
||||
}
|
||||
|
||||
|
||||
@@ -68,45 +68,47 @@ abstract class Connection
|
||||
// 数据库连接参数配置
|
||||
protected $config = [
|
||||
// 数据库类型
|
||||
'type' => '',
|
||||
'type' => '',
|
||||
// 服务器地址
|
||||
'hostname' => '',
|
||||
'hostname' => '',
|
||||
// 数据库名
|
||||
'database' => '',
|
||||
'database' => '',
|
||||
// 用户名
|
||||
'username' => '',
|
||||
'username' => '',
|
||||
// 密码
|
||||
'password' => '',
|
||||
'password' => '',
|
||||
// 端口
|
||||
'hostport' => '',
|
||||
'hostport' => '',
|
||||
// 连接dsn
|
||||
'dsn' => '',
|
||||
'dsn' => '',
|
||||
// 数据库连接参数
|
||||
'params' => [],
|
||||
'params' => [],
|
||||
// 数据库编码默认采用utf8
|
||||
'charset' => 'utf8',
|
||||
'charset' => 'utf8',
|
||||
// 数据库表前缀
|
||||
'prefix' => '',
|
||||
'prefix' => '',
|
||||
// 数据库调试模式
|
||||
'debug' => false,
|
||||
'debug' => false,
|
||||
// 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
|
||||
'deploy' => 0,
|
||||
'deploy' => 0,
|
||||
// 数据库读写是否分离 主从式有效
|
||||
'rw_separate' => false,
|
||||
'rw_separate' => false,
|
||||
// 读写分离后 主服务器数量
|
||||
'master_num' => 1,
|
||||
'master_num' => 1,
|
||||
// 指定从服务器序号
|
||||
'slave_no' => '',
|
||||
'slave_no' => '',
|
||||
// 是否严格检查字段是否存在
|
||||
'fields_strict' => true,
|
||||
'fields_strict' => true,
|
||||
// 数据集返回类型
|
||||
'resultset_type' => 'array',
|
||||
'resultset_type' => 'array',
|
||||
// 自动写入时间戳字段
|
||||
'auto_timestamp' => false,
|
||||
'auto_timestamp' => false,
|
||||
// 是否需要进行SQL性能分析
|
||||
'sql_explain' => false,
|
||||
'sql_explain' => false,
|
||||
// Builder类
|
||||
'builder' => '',
|
||||
'builder' => '',
|
||||
// 软删除字段
|
||||
'soft_delete_field' => '',
|
||||
];
|
||||
|
||||
// PDO连接参数
|
||||
|
||||
@@ -566,7 +566,11 @@ class Query
|
||||
$guid = md5($this->getTable() . '_' . $field . '_' . serialize($condition));
|
||||
$step = $this->lazyWrite('inc', $guid, $step, $lazyTime);
|
||||
if (false === $step) {
|
||||
return true; // 等待下次写入
|
||||
// 清空查询条件
|
||||
$this->options = [];
|
||||
return true;
|
||||
} else {
|
||||
return $this->setField($field, $step);
|
||||
}
|
||||
}
|
||||
return $this->setField($field, ['exp', $field . '+' . $step]);
|
||||
@@ -593,7 +597,11 @@ class Query
|
||||
$guid = md5($this->getTable() . '_' . $field . '_' . serialize($condition));
|
||||
$step = $this->lazyWrite('dec', $guid, $step, $lazyTime);
|
||||
if (false === $step) {
|
||||
return true; // 等待下次写入
|
||||
// 清空查询条件
|
||||
$this->options = [];
|
||||
return true;
|
||||
} else {
|
||||
return $this->setField($field, $step);
|
||||
}
|
||||
}
|
||||
return $this->setField($field, ['exp', $field . '-' . $step]);
|
||||
|
||||
111
core/library/traits/model/SoftDelete.php
Normal file
111
core/library/traits/model/SoftDelete.php
Normal file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
namespace traits\model;
|
||||
|
||||
trait SoftDelete
|
||||
{
|
||||
/**
|
||||
* 查询软删除数据
|
||||
* @access public
|
||||
* @return \think\db\Query
|
||||
*/
|
||||
public static function withTrashed()
|
||||
{
|
||||
$model = new static();
|
||||
return $model->db();
|
||||
}
|
||||
|
||||
/**
|
||||
* 只查询软删除数据
|
||||
* @access public
|
||||
* @return \think\db\Query
|
||||
*/
|
||||
public static function onlyTrashed()
|
||||
{
|
||||
$model = new static();
|
||||
return $model->db()->where(static::$deleteTime, '>', 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除当前的记录
|
||||
* @access public
|
||||
* @param bool $force 是否强制删除
|
||||
* @return integer
|
||||
*/
|
||||
public function delete($force = false)
|
||||
{
|
||||
if (false === $this->trigger('before_delete', $this)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (static::$deleteTime && !$force) {
|
||||
// 软删除
|
||||
$name = static::$deleteTime;
|
||||
$this->change[] = $name;
|
||||
$this->data[$name] = $this->autoWriteTimestamp($name);
|
||||
$result = $this->isUpdate()->save();
|
||||
} else {
|
||||
$result = $this->db()->delete($this->data);
|
||||
}
|
||||
|
||||
$this->trigger('after_delete', $this);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除记录
|
||||
* @access public
|
||||
* @param mixed $data 主键列表 支持闭包查询条件
|
||||
* @param bool $force 是否强制删除
|
||||
* @return integer 成功删除的记录数
|
||||
*/
|
||||
public static function destroy($data, $force = false)
|
||||
{
|
||||
$model = new static();
|
||||
$query = $model->db();
|
||||
if (is_array($data) && key($data) !== 0) {
|
||||
$query->where($data);
|
||||
$data = null;
|
||||
} elseif ($data instanceof \Closure) {
|
||||
call_user_func_array($data, [ & $query]);
|
||||
$data = null;
|
||||
}
|
||||
$resultSet = $query->select($data);
|
||||
$count = 0;
|
||||
if ($resultSet) {
|
||||
foreach ($resultSet as $data) {
|
||||
$result = $data->delete($force);
|
||||
$count += $result;
|
||||
}
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复被软删除的记录
|
||||
* @access public
|
||||
* @return integer
|
||||
*/
|
||||
public function restore()
|
||||
{
|
||||
if (static::$deleteTime) {
|
||||
// 恢复删除
|
||||
$this->setAttr(static::$deleteTime, 0);
|
||||
return $this->isUpdate()->save();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询默认不包含软删除数据
|
||||
* @access protected
|
||||
* @return void
|
||||
*/
|
||||
protected static function base($query)
|
||||
{
|
||||
if (static::$deleteTime) {
|
||||
$query->where(static::$deleteTime, 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user