mirror of
https://gitee.com/fastadminnet/framework.git
synced 2026-07-07 23:22:48 +08:00
改进Model类 简化关联操作 修正Db类参数绑定问题
This commit is contained in:
@@ -15,6 +15,11 @@ use think\Cache;
|
|||||||
|
|
||||||
abstract class Model implements \JsonSerializable, \ArrayAccess
|
abstract class Model implements \JsonSerializable, \ArrayAccess
|
||||||
{
|
{
|
||||||
|
const HAS_ONE = 1;
|
||||||
|
const HAS_MANY = 2;
|
||||||
|
const BELONGS_TO = 3;
|
||||||
|
const BELONGS_TO_MANY = 4;
|
||||||
|
|
||||||
// 当前实例
|
// 当前实例
|
||||||
private static $instance;
|
private static $instance;
|
||||||
// 数据库对象池
|
// 数据库对象池
|
||||||
@@ -46,8 +51,9 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
protected $insert = [];
|
protected $insert = [];
|
||||||
// 更新的字段完成
|
// 更新的字段完成
|
||||||
protected $update = [];
|
protected $update = [];
|
||||||
// 关联
|
|
||||||
protected $relation = [];
|
// 当前执行的关联类型
|
||||||
|
private $relation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 架构函数
|
* 架构函数
|
||||||
@@ -155,12 +161,27 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
if (method_exists($this, $method)) {
|
if (method_exists($this, $method)) {
|
||||||
return $this->$method($value, $this->data);
|
return $this->$method($value, $this->data);
|
||||||
}
|
}
|
||||||
if (is_null($value)) {
|
if (is_null($value) && method_exists($this, $name)) {
|
||||||
// 检测关联数据
|
// 执行关联定义方法 ( 关联定义方法始终返回Db对象)
|
||||||
$method = 'getRelation' . Loader::parseName($name, 1);
|
$db = $this->$name();
|
||||||
if (method_exists($this, $method)) {
|
// 判断关联类型执行查询
|
||||||
return $this->$method();
|
switch ($this->relation) {
|
||||||
|
case self::HAS_ONE:
|
||||||
|
$result = $db->find();
|
||||||
|
break;
|
||||||
|
case self::HAS_MANY:
|
||||||
|
$result = $db->select();
|
||||||
|
break;
|
||||||
|
case self::BELONGS_TO:
|
||||||
|
$result = $db->find();
|
||||||
|
break;
|
||||||
|
case self::BELONGS_TO_MANY:
|
||||||
|
$result = $db->select();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
// 避免影响其它操作方法
|
||||||
|
$this->relation = null;
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
@@ -205,12 +226,19 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存当前数据对象的值 无需任何参数(自动识别新增或者更新)
|
* 保存当前数据对象的值(自动识别新增或者更新)
|
||||||
* @access public
|
* @access public
|
||||||
|
* @param array $data 数据
|
||||||
|
* @param array $where 更新条件
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function save()
|
public function save($data = [], $where = [])
|
||||||
{
|
{
|
||||||
|
if (!empty($data)) {
|
||||||
|
foreach ($data as $key => $value) {
|
||||||
|
$this->__set($key, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
$data = $this->data;
|
$data = $this->data;
|
||||||
|
|
||||||
// 数据自动验证
|
// 数据自动验证
|
||||||
@@ -226,9 +254,10 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
$data[$name] = is_callable($rule) ? call_user_func_array($rule, [ & $data]) : $rule;
|
$data[$name] = is_callable($rule) ? call_user_func_array($rule, [ & $data]) : $rule;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->checkPkExists($data)) {
|
// 检测是否为更新数据
|
||||||
|
if ($this->isUpdate($data)) {
|
||||||
|
|
||||||
if (false === self::trigger('before_update', $data)) {
|
if (false === $this->trigger('before_update', $this)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// 更新的时候检测字段更改
|
// 更新的时候检测字段更改
|
||||||
@@ -245,21 +274,17 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
$data[$name] = is_callable($rule) ? call_user_func_array($rule, [ & $data]) : $rule;
|
$data[$name] = is_callable($rule) ? call_user_func_array($rule, [ & $data]) : $rule;
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = self::db()->update($data);
|
$db = self::db();
|
||||||
|
if (!empty($where)) {
|
||||||
// 关联更新
|
$db->where($where);
|
||||||
if (!empty($this->relation)) {
|
|
||||||
foreach ($this->relation as $key => $val) {
|
|
||||||
if (isset($data[$key])) {
|
|
||||||
$this->relationUpdate($key, $data[$key], $val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
self::trigger('after_update', $data);
|
$result = $db->update($data);
|
||||||
|
|
||||||
|
$this->trigger('after_update', $this);
|
||||||
return $result;
|
return $result;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (false === self::trigger('before_insert', $data)) {
|
if (false === $this->trigger('before_insert', $this)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,15 +302,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
$this->data[$this->pk] = $insertId;
|
$this->data[$this->pk] = $insertId;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关联写入
|
$this->trigger('after_insert', $this);
|
||||||
if (!empty($this->relation)) {
|
|
||||||
foreach ($this->relation as $key => $val) {
|
|
||||||
if (isset($data[$key])) {
|
|
||||||
$this->relationInsert($key, $data[$key], $val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self::trigger('after_insert', $data);
|
|
||||||
return $insertId ?: $result;
|
return $insertId ?: $result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -299,21 +316,13 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
{
|
{
|
||||||
$data = $this->data;
|
$data = $this->data;
|
||||||
|
|
||||||
if (false === self::trigger('before_delete', $data)) {
|
if (false === $this->trigger('before_delete', $this)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = self::db()->delete($data);
|
$result = self::db()->delete($data);
|
||||||
|
|
||||||
// 关联删除
|
$this->trigger('after_delete', $this);
|
||||||
if ($result) {
|
|
||||||
if (!empty($this->relation)) {
|
|
||||||
foreach ($this->relation as $key => $val) {
|
|
||||||
$this->relationDelete($key, $data, $val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self::trigger('after_delete', $data);
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -422,12 +431,12 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查数据中是否存在主键值
|
* 是否为更新操作
|
||||||
* @access public
|
* @access public
|
||||||
* @param mixed $data 数据
|
* @param mixed $data 数据
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function checkPkExists($data = [])
|
public function isUpdate($data = [])
|
||||||
{
|
{
|
||||||
$data = $data ?: $this->data;
|
$data = $data ?: $this->data;
|
||||||
$pk = $this->pk;
|
$pk = $this->pk;
|
||||||
@@ -442,6 +451,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// TODO 完善没有主键或者其他的情况
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -472,7 +482,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
* @param string $event 事件名
|
* @param string $event 事件名
|
||||||
* @param mixed $params 传入参数(引用)
|
* @param mixed $params 传入参数(引用)
|
||||||
*/
|
*/
|
||||||
protected static function trigger($event, &$params)
|
protected function trigger($event, &$params)
|
||||||
{
|
{
|
||||||
if (isset(self::$event[$event]) && is_callable(self::$event[$event])) {
|
if (isset(self::$event[$event]) && is_callable(self::$event[$event])) {
|
||||||
$result = call_user_func_array(self::$event[$event], [ & $params]);
|
$result = call_user_func_array(self::$event[$event], [ & $params]);
|
||||||
@@ -536,26 +546,17 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
* 删除记录
|
* 删除记录
|
||||||
* @access public
|
* @access public
|
||||||
* @param mixed $data 主键列表
|
* @param mixed $data 主键列表
|
||||||
* @param bool $findFirst 是否查询
|
|
||||||
* @return integer
|
* @return integer
|
||||||
*/
|
*/
|
||||||
public static function destroy($data, $findFirst = false)
|
public static function destroy($data)
|
||||||
{
|
{
|
||||||
// 保留删除的数据备用
|
$model = new static();
|
||||||
if ($findFirst) {
|
$resultSet = $model->select($data);
|
||||||
$resultSet = self::all($data);
|
if ($resultSet) {
|
||||||
|
foreach ($resultSet as $data) {
|
||||||
|
$result = $data->delete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (false === self::trigger('before_delete', $findFirst ? $resultSet : $data)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = self::db()->delete($data);
|
|
||||||
|
|
||||||
// 关联删除
|
|
||||||
|
|
||||||
// 删除回调
|
|
||||||
self::trigger('after_delete', $findFirst ? $resultSet : $data);
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -571,136 +572,44 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
return $model;
|
return $model;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 指定关联
|
|
||||||
public function relation($name, $relation = '')
|
|
||||||
{
|
|
||||||
if (is_array($name)) {
|
|
||||||
$this->relation = array_merge($this->relation, $name);
|
|
||||||
} else {
|
|
||||||
$this->relation[$name] = $relation;
|
|
||||||
}
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// HAS ONE
|
// HAS ONE
|
||||||
public function hasOne($model, $foreignKey = '', $localKey = '')
|
public function hasOne($model, $foreignKey = '', $localKey = '')
|
||||||
{
|
{
|
||||||
$model = $this->parseModel($model);
|
$model = $this->parseModel($model);
|
||||||
$localKey = $localKey ?: $this->pk;
|
$localKey = $localKey ?: $this->pk;
|
||||||
$foreignKey = $foreignKey ?: $this->name . '_id';
|
$foreignKey = $foreignKey ?: $this->name . '_id';
|
||||||
return $model::where($foreignKey, $this->data[$localKey])->find();
|
$this->relation = self::HAS_ONE;
|
||||||
|
return $model::where($foreignKey, $this->data[$localKey]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// BELONGS TO
|
// BELONGS TO
|
||||||
public function belongsTo($model, $localKey = '', $foreignKey = '')
|
public function belongsTo($model, $localKey = '', $foreignKey = '')
|
||||||
{
|
{
|
||||||
$model = $this->parseModel($model);
|
$model = $this->parseModel($model);
|
||||||
$foreignKey = $foreignKey ?: $this->pk;
|
$foreignKey = $foreignKey ?: $this->pk;
|
||||||
$localKey = $localKey ?: basename(str_replace('\\', '/', $model)) . '_id';
|
$localKey = $localKey ?: basename(str_replace('\\', '/', $model)) . '_id';
|
||||||
return $model::where($foreignKey, $this->data[$localKey])->find();
|
$this->relation = self::BELONGS_TO;
|
||||||
|
return $model::where($foreignKey, $this->data[$localKey]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// HAS MANY
|
// HAS MANY
|
||||||
public function hasMany($model, $foreignKey = '', $localKey = '')
|
public function hasMany($model, $foreignKey = '', $localKey = '')
|
||||||
{
|
{
|
||||||
$model = $this->parseModel($model);
|
$model = $this->parseModel($model);
|
||||||
$localKey = $localKey ?: $this->pk;
|
$localKey = $localKey ?: $this->pk;
|
||||||
$foreignKey = $foreignKey ?: $this->name . '_id';
|
$foreignKey = $foreignKey ?: $this->name . '_id';
|
||||||
return $model::where($foreignKey, $this->data[$localKey])->select();
|
$this->relation = self::HAS_MANY;
|
||||||
|
return $model::where($foreignKey, $this->data[$localKey]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// BELONGS TO MANY
|
// BELONGS TO MANY
|
||||||
public function belongsToMany($model, $localKey = '', $foreignKey = '')
|
public function belongsToMany($model, $localKey = '', $foreignKey = '')
|
||||||
{
|
{
|
||||||
$model = $this->parseModel($model);
|
$model = $this->parseModel($model);
|
||||||
$foreignKey = $foreignKey ?: $this->pk;
|
$foreignKey = $foreignKey ?: $this->pk;
|
||||||
$localKey = $localKey ?: basename(str_replace('\\', '/', $model)) . '_id';
|
$localKey = $localKey ?: basename(str_replace('\\', '/', $model)) . '_id';
|
||||||
return $model::where($foreignKey, $this->data[$localKey])->select();
|
$this->relation = self::BELONGS_TO_MANY;
|
||||||
}
|
return $model::where($foreignKey, $this->data[$localKey]);
|
||||||
|
|
||||||
// 关联写入
|
|
||||||
public function relationInsert($className, $data, $relation = [])
|
|
||||||
{
|
|
||||||
if (empty($relation) && isset($this->relation[$className])) {
|
|
||||||
$relation = $this->relation[$className];
|
|
||||||
}
|
|
||||||
$type = isset($relation['relation_type']) ? $relation['relation_type'] : $relation;
|
|
||||||
$foreignKey = isset($relation['foreign_key']) ? $relation['foreign_key'] : strtolower($this->name) . '_id';
|
|
||||||
$className = isset($relation['class_name']) ? $relation['class_name'] : $className;
|
|
||||||
|
|
||||||
$model = $this->parseModel(ucfirst($className));
|
|
||||||
switch ($type) {
|
|
||||||
case 'has_one':
|
|
||||||
$data[$foreignKey] = $this->data[$this->pk];
|
|
||||||
$model::create($data);
|
|
||||||
break;
|
|
||||||
case 'belongs_to':
|
|
||||||
break;
|
|
||||||
case 'has_many':
|
|
||||||
foreach ($data as $key => &$val) {
|
|
||||||
$val[$foreignKey] = $this->data[$this->pk];
|
|
||||||
}
|
|
||||||
$model::insertAll($data);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 关联更新
|
|
||||||
public function relationUpdate($className, $data, $relation = [])
|
|
||||||
{
|
|
||||||
if (empty($relation) && isset($this->relation[$className])) {
|
|
||||||
$relation = $this->relation[$className];
|
|
||||||
}
|
|
||||||
$type = isset($relation['relation_type']) ? $relation['relation_type'] : $relation;
|
|
||||||
$foreignKey = isset($relation['foreign_key']) ? $relation['foreign_key'] : strtolower($this->name) . '_id';
|
|
||||||
$className = isset($relation['class_name']) ? $relation['class_name'] : $className;
|
|
||||||
|
|
||||||
$model = $this->parseModel(ucfirst($className));
|
|
||||||
switch ($type) {
|
|
||||||
case 'has_one':
|
|
||||||
$class = new $model;
|
|
||||||
if ($class->checkPkExists($data)) {
|
|
||||||
$class::update($data);
|
|
||||||
} else {
|
|
||||||
$class::where($foreignKey, $this->data[$this->pk])->update($data);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'belongs_to':
|
|
||||||
break;
|
|
||||||
case 'has_many':
|
|
||||||
$class = new $model;
|
|
||||||
foreach ($data as $key => $val) {
|
|
||||||
$class::update($val);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 关联删除
|
|
||||||
public function relationDelete($className, $data = '', $relation = [])
|
|
||||||
{
|
|
||||||
if (empty($relation) && isset($this->relation[$className])) {
|
|
||||||
$relation = $this->relation[$className];
|
|
||||||
}
|
|
||||||
$type = isset($relation['relation_type']) ? $relation['relation_type'] : $relation;
|
|
||||||
$foreignKey = isset($relation['foreign_key']) ? $relation['foreign_key'] : strtolower($this->name) . '_id';
|
|
||||||
$className = isset($relation['class_name']) ? $relation['class_name'] : $className;
|
|
||||||
|
|
||||||
$model = $this->parseModel(ucfirst($className));
|
|
||||||
$id = $data ? $data[$this->pk] : $this->data[$this->pk];
|
|
||||||
switch ($type) {
|
|
||||||
case 'has_one':
|
|
||||||
$model::where($foreignKey, $id)->delete();
|
|
||||||
break;
|
|
||||||
case 'belongs_to':
|
|
||||||
break;
|
|
||||||
case 'has_many':
|
|
||||||
$model::where($foreignKey, $id)->delete();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return $this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,78 +0,0 @@
|
|||||||
<?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: liu21st <liu21st@gmail.com>
|
|
||||||
// +----------------------------------------------------------------------
|
|
||||||
|
|
||||||
namespace think;
|
|
||||||
|
|
||||||
class ORM
|
|
||||||
{
|
|
||||||
protected static $instance = [];
|
|
||||||
protected static $config = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置数据对象的值
|
|
||||||
* @access public
|
|
||||||
* @param string $name 名称
|
|
||||||
* @param mixed $value 值
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function __set($name, $value)
|
|
||||||
{
|
|
||||||
self::__callStatic('__set', [$name, $value]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取数据对象的值
|
|
||||||
* @access public
|
|
||||||
* @param string $name 名称
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function __get($name)
|
|
||||||
{
|
|
||||||
return self::__callStatic('__get', [$name]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检测数据对象的值
|
|
||||||
* @access public
|
|
||||||
* @param string $name 名称
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function __isset($name)
|
|
||||||
{
|
|
||||||
return self::__callStatic('__isset', [$name]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 销毁数据对象的值
|
|
||||||
* @access public
|
|
||||||
* @param string $name 名称
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function __unset($name)
|
|
||||||
{
|
|
||||||
self::__callStatic('__unset', [$name]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __call($method, $params)
|
|
||||||
{
|
|
||||||
return self::__callStatic($method, $params);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function __callStatic($method, $params)
|
|
||||||
{
|
|
||||||
$name = basename(str_replace('\\', '/', get_called_class()));
|
|
||||||
if (!isset(self::$instance[$name])) {
|
|
||||||
// 自动实例化模型类
|
|
||||||
self::$instance[$name] = new \think\Model($name, static::$config);
|
|
||||||
}
|
|
||||||
return call_user_func_array([self::$instance[$name], $method], $params);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -963,9 +963,9 @@ abstract class Driver
|
|||||||
public function bind($key, $value = false, $type = PDO::PARAM_STR)
|
public function bind($key, $value = false, $type = PDO::PARAM_STR)
|
||||||
{
|
{
|
||||||
if (is_array($key)) {
|
if (is_array($key)) {
|
||||||
$this->options['bind'] = $key;
|
$this->bind = array_merge($this->bind, $key);
|
||||||
} else {
|
} else {
|
||||||
$this->options['bind'][$key] = [$value, $type];
|
$this->bind[$key] = [$value, $type];
|
||||||
}
|
}
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@@ -1224,16 +1224,16 @@ abstract class Driver
|
|||||||
if (isset($options['where']['AND'])) {
|
if (isset($options['where']['AND'])) {
|
||||||
foreach ($options['where']['AND'] as $key => $val) {
|
foreach ($options['where']['AND'] as $key => $val) {
|
||||||
$key = trim($key);
|
$key = trim($key);
|
||||||
if (in_array($key, $fields, true) && is_scalar($val) && empty($options['bind'][$key])) {
|
if (in_array($key, $fields, true) && is_scalar($val) && empty($this->bind[$key])) {
|
||||||
$this->_parseType($options['where']['AND'], $key, $options['bind'], $options['table']);
|
$this->_parseType($options['where']['AND'], $key, $options['table']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isset($options['where']['OR'])) {
|
if (isset($options['where']['OR'])) {
|
||||||
foreach ($options['where']['OR'] as $key => $val) {
|
foreach ($options['where']['OR'] as $key => $val) {
|
||||||
$key = trim($key);
|
$key = trim($key);
|
||||||
if (in_array($key, $fields, true) && is_scalar($val) && empty($options['bind'][$key])) {
|
if (in_array($key, $fields, true) && is_scalar($val) && empty($this->bind[$key])) {
|
||||||
$this->_parseType($options['where']['OR'], $key, $options['bind'], $options['table']);
|
$this->_parseType($options['where']['OR'], $key, $options['table']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1244,9 +1244,6 @@ abstract class Driver
|
|||||||
$options['table'] .= ' ' . $options['alias'];
|
$options['table'] .= ' ' . $options['alias'];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 参数绑定 全局化
|
|
||||||
$this->bind = !empty($options['bind']) ? $options['bind'] : [];
|
|
||||||
|
|
||||||
// 查询过后清空sql表达式组装 避免影响下次查询
|
// 查询过后清空sql表达式组装 避免影响下次查询
|
||||||
$this->options = [];
|
$this->options = [];
|
||||||
return $options;
|
return $options;
|
||||||
@@ -1257,13 +1254,12 @@ abstract class Driver
|
|||||||
* @access protected
|
* @access protected
|
||||||
* @param array $data 数据
|
* @param array $data 数据
|
||||||
* @param string $key 字段名
|
* @param string $key 字段名
|
||||||
* @param array $bind 参数绑定列表
|
|
||||||
* @param string $tableName 表名
|
* @param string $tableName 表名
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function _parseType(&$data, $key, &$bind, $tableName = '')
|
protected function _parseType(&$data, $key, $tableName = '')
|
||||||
{
|
{
|
||||||
if (':' == substr($data[$key], 0, 1) && isset($bind[substr($data[$key], 1)])) {
|
if (':' == substr($data[$key], 0, 1) && isset($this->bind[substr($data[$key], 1)])) {
|
||||||
// 已经绑定 无需再次绑定 请确保bind方法优先执行
|
// 已经绑定 无需再次绑定 请确保bind方法优先执行
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1277,8 +1273,8 @@ abstract class Driver
|
|||||||
} elseif (false !== strpos($type[$key], 'bool')) {
|
} elseif (false !== strpos($type[$key], 'bool')) {
|
||||||
$data[$key] = (bool) $data[$key];
|
$data[$key] = (bool) $data[$key];
|
||||||
}
|
}
|
||||||
$bind[$key] = [$data[$key], isset($binds[$key]) ? $binds[$key] : \PDO::PARAM_STR];
|
$this->bind[$key] = [$data[$key], isset($binds[$key]) ? $binds[$key] : \PDO::PARAM_STR];
|
||||||
$data[$key] = ':' . $key;
|
$data[$key] = ':' . $key;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1345,7 +1341,7 @@ abstract class Driver
|
|||||||
$result[$item] = 'NULL';
|
$result[$item] = 'NULL';
|
||||||
} elseif (is_scalar($val)) {
|
} elseif (is_scalar($val)) {
|
||||||
// 过滤非标量数据
|
// 过滤非标量数据
|
||||||
$this->_parseType($data, $key, $this->bind);
|
$this->_parseType($data, $key);
|
||||||
$result[$item] = $data[$key];
|
$result[$item] = $data[$key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1712,6 +1708,19 @@ abstract class Driver
|
|||||||
return sprintf(" FORCE INDEX ( %s ) ", $index);
|
return sprintf(" FORCE INDEX ( %s ) ", $index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取参数绑定信息并清空
|
||||||
|
* @access protected
|
||||||
|
* @param bool $reset 获取后清空
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function getBindParams()
|
||||||
|
{
|
||||||
|
$bind = $this->bind;
|
||||||
|
$this->bind = [];
|
||||||
|
return $bind;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 插入记录
|
* 插入记录
|
||||||
* @access public
|
* @access public
|
||||||
@@ -1730,7 +1739,7 @@ abstract class Driver
|
|||||||
// 兼容数字传入方式
|
// 兼容数字传入方式
|
||||||
$sql = ($replace ? 'REPLACE' : 'INSERT') . ' INTO ' . $this->parseTable($options['table']) . ' (' . implode(',', $fields) . ') VALUES (' . implode(',', $values) . ')';
|
$sql = ($replace ? 'REPLACE' : 'INSERT') . ' INTO ' . $this->parseTable($options['table']) . ' (' . implode(',', $fields) . ') VALUES (' . implode(',', $values) . ')';
|
||||||
$sql .= $this->parseComment(!empty($options['comment']) ? $options['comment'] : '');
|
$sql .= $this->parseComment(!empty($options['comment']) ? $options['comment'] : '');
|
||||||
$result = $this->execute($sql, isset($options['bind']) ? $options['bind'] : [], !empty($options['fetch_sql']) ? true : false);
|
$result = $this->execute($sql, $this->getBindParams(), !empty($options['fetch_sql']) ? true : false);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1755,7 +1764,7 @@ abstract class Driver
|
|||||||
}
|
}
|
||||||
$sql = 'INSERT INTO ' . $this->parseTable($options['table']) . ' (' . implode(',', $fields) . ') ' . implode(' UNION ALL ', $values);
|
$sql = 'INSERT INTO ' . $this->parseTable($options['table']) . ' (' . implode(',', $fields) . ') ' . implode(' UNION ALL ', $values);
|
||||||
$sql .= $this->parseComment(!empty($options['comment']) ? $options['comment'] : '');
|
$sql .= $this->parseComment(!empty($options['comment']) ? $options['comment'] : '');
|
||||||
return $this->execute($sql, isset($options['bind']) ? $options['bind'] : [], !empty($options['fetch_sql']) ? true : false);
|
return $this->execute($sql, $this->getBindParams(), !empty($options['fetch_sql']) ? true : false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1776,7 +1785,7 @@ abstract class Driver
|
|||||||
$fields = array_map([$this, 'parseKey'], $fields);
|
$fields = array_map([$this, 'parseKey'], $fields);
|
||||||
$sql = 'INSERT INTO ' . $this->parseTable($table) . ' (' . implode(',', $fields) . ') ';
|
$sql = 'INSERT INTO ' . $this->parseTable($table) . ' (' . implode(',', $fields) . ') ';
|
||||||
$sql .= $this->buildSelectSql($options);
|
$sql .= $this->buildSelectSql($options);
|
||||||
return $this->execute($sql, isset($options['bind']) ? $options['bind'] : [], !empty($options['fetch_sql']) ? true : false);
|
return $this->execute($sql, $this->getBindParams(), !empty($options['fetch_sql']) ? true : false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1833,7 +1842,7 @@ abstract class Driver
|
|||||||
. $this->parseLimit(!empty($options['limit']) ? $options['limit'] : '');
|
. $this->parseLimit(!empty($options['limit']) ? $options['limit'] : '');
|
||||||
}
|
}
|
||||||
$sql .= $this->parseComment(!empty($options['comment']) ? $options['comment'] : '');
|
$sql .= $this->parseComment(!empty($options['comment']) ? $options['comment'] : '');
|
||||||
return $this->execute($sql, isset($options['bind']) ? $options['bind'] : [], !empty($options['fetch_sql']) ? true : false);
|
return $this->execute($sql, $this->getBindParams(), !empty($options['fetch_sql']) ? true : false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1871,7 +1880,7 @@ abstract class Driver
|
|||||||
. $this->parseLimit(!empty($options['limit']) ? $options['limit'] : '');
|
. $this->parseLimit(!empty($options['limit']) ? $options['limit'] : '');
|
||||||
}
|
}
|
||||||
$sql .= $this->parseComment(!empty($options['comment']) ? $options['comment'] : '');
|
$sql .= $this->parseComment(!empty($options['comment']) ? $options['comment'] : '');
|
||||||
return $this->execute($sql, isset($options['bind']) ? $options['bind'] : [], !empty($options['fetch_sql']) ? true : false);
|
return $this->execute($sql, $this->getBindParams(), !empty($options['fetch_sql']) ? true : false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildSql($sub = true)
|
public function buildSql($sub = true)
|
||||||
@@ -1897,7 +1906,7 @@ abstract class Driver
|
|||||||
|
|
||||||
$options = $this->_parseOptions();
|
$options = $this->_parseOptions();
|
||||||
$sql = $this->buildSelectSql($options);
|
$sql = $this->buildSelectSql($options);
|
||||||
$resultSet = $this->query($sql, isset($options['bind']) ? $options['bind'] : [], !empty($options['fetch_sql']) ? true : false, !empty($options['master']) ? true : false, isset($options['fetch_mode']) ? $options['fetch_mode'] : true);
|
$resultSet = $this->query($sql, $this->getBindParams(), !empty($options['fetch_sql']) ? true : false, !empty($options['master']) ? true : false, isset($options['fetch_mode']) ? $options['fetch_mode'] : true);
|
||||||
|
|
||||||
if (!empty($resultSet)) {
|
if (!empty($resultSet)) {
|
||||||
if (is_string($resultSet)) {
|
if (is_string($resultSet)) {
|
||||||
@@ -1970,7 +1979,7 @@ abstract class Driver
|
|||||||
$options = $this->_parseOptions();
|
$options = $this->_parseOptions();
|
||||||
$options['limit'] = 1;
|
$options['limit'] = 1;
|
||||||
$sql = $this->buildSelectSql($options);
|
$sql = $this->buildSelectSql($options);
|
||||||
$result = $this->query($sql, isset($options['bind']) ? $options['bind'] : [], !empty($options['fetch_sql']) ? true : false, !empty($options['master']) ? true : false, isset($options['fetch_mode']) ? $options['fetch_mode'] : true);
|
$result = $this->query($sql, $this->getBindParams(), !empty($options['fetch_sql']) ? true : false, !empty($options['master']) ? true : false, isset($options['fetch_mode']) ? $options['fetch_mode'] : true);
|
||||||
|
|
||||||
// 数据处理
|
// 数据处理
|
||||||
if (!empty($result)) {
|
if (!empty($result)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user