/**
* 设置需要追加的输出属性
* @access public
* @param array $append 属性列表
* @return $this
*/
public function append($append = [])
{
$this->append = $append;// 属性追加
return $this;
}
/**
* 设置需要隐藏的输出属性
* @access public
* @param array $hidden 属性列表
* @return $this
*/
public function hidden($hidden = [])
{
$this->hidden = $hidden;// 属性隐藏
return $this;
}
/**
* 设置需要输出的属性
* @param array $visible
* @return $this
*/
public function visible($visible = [])
{
$this->visible = $visible;// 输出的属性
return $this;
}
/**
* 转换当前模型对象为数组
* @access public
* @return array
*/
public function toArray()
{
$item = [];
//过滤属性
if (!empty($this->visible)) {
$data = array_intersect_key($this->data, array_flip($this->visible));
} elseif (!empty($this->hidden)) {
$data = array_diff_key($this->data, array_flip($this->hidden));
} else {
$data = $this->data;
}
foreach ($data as $key => $val) {
if ($val instanceof Model || $val instanceof Collection) {
// 关联模型对象
$item[$key] = $val->toArray();
} elseif (is_array($val) && reset($val) instanceof Model) {
// 关联模型数据集
$arr = [];
foreach ($val as $k => $value) {
$arr[$k] = $value->toArray();
}
$item[$key] = $arr;
} else {
// 模型属性
$item[$key] = $this->getAttr($key);
}
}
// 追加属性(必须定义获取器)
if (!empty($this->append)) {
foreach ($this->append as $name) {
$item[$name] = $this->getAttr($name);
}
}
return !empty($item) ? $item : [];
}// 转换为数组
/**
* 转换当前模型对象为JSON字符串
* @access public
* @param integer $options json参数
* @return string
*/
public function toJson($options = JSON_UNESCAPED_UNICODE)
{
return json_encode($this->toArray(), $options);// 转换wield json
}
/**
* 获取模型对象的主键
* @access public
* @param string $name 模型名
* @return mixed
*/
public function getPk($name = '')
{// 获取主键
if (!empty($name)) {
$table = $this->db()->getTable($name);
return $this->db()->getPk($table);
} elseif (empty($this->pk)) {
$this->pk = $this->db()->getPk();
}
return $this->pk;
}
/**
* 判断一个字段名是否为主键字段
* @access public
* @param string $key 名称
* @return bool
*/
protected function isPk($key)
{// 检测是否为主键
$pk = $this->getPk();
if (is_string($pk) && $pk == $key) {
return true;
} elseif (is_array($pk) && in_array($key, $pk)) {
return true;
}
return false;
}
/**
* 保存当前数据对象
* @access public
* @param array $data 数据
* @param array $where 更新条件
* @param string $sequence 自增序列名
* @return integer|false
*/
public function save($data = [], $where = [], $sequence = null)
{// 数据保存
if (!empty($data)) {// 数据不为空
// 数据自动验证
if (!$this->validateData($data)) {
return false;
}
// 数据对象赋值
foreach ($data as $key => $value) {// 数据对象赋值
$this->setAttr($key, $value, $data);
}
if (!empty($where)) {// 条件不为空 代表为 更新状态
$this->isUpdate = true;
}
}
// 检测字段
if (!empty($this->field)) {// 字段不为空
$this->db();
foreach ($this->data as $key => $val) {// 删除数据里面的 多有的字段信息
if (!in_array($key, $this->field)) {
unset($this->data[$key]);
}
}
}
// 数据自动完成
$this->autoCompleteData($this->auto);// 数据自动完成
// 自动写入更新时间
if ($this->autoWriteTimestamp && $this->updateTime) {// 时间属性设置
$this->setAttr($this->updateTime, null);
}
// 事件回调
if (false === $this->trigger('before_write', $this)) {// 回调
return false;
}
if ($this->isUpdate) {// 执行更新
// 自动更新
$this->autoCompleteData($this->update);
// 事件回调
if (false === $this->trigger('before_update', $this)) {
return false;
}
// 去除没有更新的字段
$data = [];
foreach ($this->data as $key => $val) {
if (in_array($key, $this->change) || $this->isPk($key)) {
$data[$key] = $val;
}
}
if (!empty($this->readonly)) {
// 只读字段不允许更新
foreach ($this->readonly as $key => $field) {
if (isset($data[$field])) {
unset($data[$field]);
}
}
}
if (empty($where) && !empty($this->updateWhere)) {
$where = $this->updateWhere;
}
if (!empty($where)) {
$pk = $this->getPk();
if (is_string($pk) && isset($data[$pk])) {
unset($data[$pk]);
}
}
$result = $this->db()->where($where)->update($data);// 还是使用数据库 模型的更新
// 清空change
$this->change = [];
// 更新回调
$this->trigger('after_update', $this);
} else {
// 自动写入
$this->autoCompleteData($this->insert);
// 自动写入创建时间
if ($this->autoWriteTimestamp && $this->createTime) {
$this->setAttr($this->createTime, null);
}
if (false === $this->trigger('before_insert', $this)) {
return false;
}
$result = $this->db()->insert($this->data);// 数据模型的插入
// 获取自动增长主键
if ($result) {
$insertId = $this->db()->getLastInsID($sequence);// 获取自动增长的主键
$pk = $this->getPk();
if (is_string($pk) && $insertId) {
$this->data[$pk] = $insertId;
}
}
// 标记为更新
$this->isUpdate = true;
// 清空change
$this->change = [];
// 新增回调
$this->trigger('after_insert', $this);
}
// 写入回调
$this->trigger('after_write', $this);
return $result;
}
/**
* 保存多个数据到当前数据对象
* @access public
* @param array $dataSet 数据
* @param boolean $replace 是否自动识别更新和写入
* @return array|false
*/
public function saveAll($dataSet, $replace = true)// 基于事务的 批量插入及更新
{
if ($this->validate) {//批量数据验证
// 数据批量验证
$validate = $this->validate;
foreach ($dataSet as $data) {
if (!$this->validate($validate)->validateData($data)) {
return false;
}
}
}
$result = [];
$db = $this->db();
$db->startTrans();// 启动事务
try {
$pk = $this->getPk();
if (is_string($pk) && $replace) {
$auto = true;
}
foreach ($dataSet as $key => $data) {
if (!empty($auto) && isset($data[$pk])) {
$result[$key] = self::update($data);
} else {
$result[$key] = self::create($data);
}
}
$db->commit();// 提交事务
return $result;
} catch (\Exception $e) {
$db->rollback();// 否则回滚
throw $e;
}
}
[李景山php]每天TP5-20170111|thinkphp5-Model.php-4
原创
©著作权归作者所有:来自51CTO博客作者lijingshan34的原创作品,请联系作者获取转载授权,否则将追究法律责任
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章