我们更希望看到:
// 新增对象至数据表
$result = $Teacher->validate(true)->save();
而不是:
// 新增对象至数据表
$result = $Teacher->validate(true)->save($Teacher->getData());
原因很简单的,上面的写法才是真正的面象对象。正确的思想是:我们给一个对象赋值,然后对这个对象进行验证。显然,上面的写法更贴近我们的真实想法。
ThinkPHP是一个开源的软件,我们可以在Github中,找到它的身影 。下一个贡献者会不会就是你呢?
在这里,为了更好的实现验证,我们对think\Model及think\Validate类进行改写。
如果你并不想动框架的源代码,那么可以略过下面本节中我们下面要讲的内容。只需要在以后涉及到验证操作时,使用$Teacher->validate(true)->save($Teacher->getData());即可。
一、think\Model类文件的位于thinkphp/library/think/Model.php 1、我们找到其中的save方法,改写前:
public function save($data = [], $where = [], $sequence = null)
{
if (!empty($data)) {
// 数据自动验证 千锋PHP-PHP培训的实力派
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]);
}
}
}
...
改写后:
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;
}
// 未传入数据,则依新增与更新分别进行验证 --- 梦云智
} else {
// 更新,只验证有变化的值
if ($this->isUpdate && !empty($this->change)) {
foreach ($this->change as $value) {
$data[$value] = $this->getData($value);
}
// 新增,验证全部的值
} else {
$data = $this->getData();
}
// 数据自动验证
if (!$this->validateData($data, $this->isUpdate)) {
return false;
}
}
// 检测字段
if (!empty($this->field)) {
$this->db();
foreach ($this->data as $key => $val) {
if (!in_array($key, $this->field)) {
unset($this->data[$key]);
}
}
}
...
2、我们再找到该文件中的validateData方法
改写前:
/**
* 自动验证数据
* @access protected
* @param array $data 验证数据
* @return bool
*/
protected function validateData($data)
...
$validate = Loader::validate($name);
if (!empty($scene)) {
$validate->scene($scene);
}
}
if (!$validate->check($data)) {
...
改写后:
/**
* 自动验证数据
* @access protected
* @param array $data 验证数据
* @param bool $isUpdate
* @return bool
*/
protected function validateData($data, $isUpdate = false)
...
$validate = Loader::validate($name);
if (!empty($scene)) {
$validate->scene($scene);
}
}
// 进行数据更新操作则只验证有变化的字段 --- 梦云智
if ($isUpdate) {
$validate->reMakeRule($data);
}
if (!$validate->check($data)) {
...
二、 think\Validate类文件的位于thinkphp/library/think/Validate.php 在类中新增reMakeRule方法,比如我在rule()方法后后面进行添加。
/**
* 重新生成规则 (删除规则中不存在的更新字段规则 )
* @param array $datas 要验证的数据
* @return
*/
public function reMakeRule($datas = [])
{
$rule = [];
if (is_array($datas)) {
foreach ($datas as $key => $data) {
if (array_key_exists($key, $this->rule)) {
$rule[$key] = $this->rule[$key];
}
}
}
$this->rule = $rule;
}
有了上述代码后,我们在C层就可以这样使用了。
// 新增对象至数据表
$result = $Teacher->validate(true)->save();
测试: