thinkPHP使用中踩的坑,记录一下(不停更)

版本3.2.3

1、数据库操作中的连贯操作table(),在查询的时候可以切换表,但是在插入,更新的时候请不要使用。例如

D('user')->table('auth')->add($data);

操作会出问题,因为插入的时候会把非user表的字段删除

2.数据库操作的create(),如果使用了框架的自动验证功能,在create()时会验证字段的合法性,有时候我们会多次create,进行批量添加或者修改,这时候会出问题。查看源码,发现是因为里面的$error属性没有重置。设置Model的$patchValidate为true是一种办法,但是会导致返回的错误不再是一个字符串,而是数组,并且即使已经有不合法的字段了,还是会继续验证其他字段,解决办法是

//重写create方法,每次create,清空error
    public function create($data = '', $type = '')
    {
        $this->error = array();
        return parent::create($data, $type); // TODO: Change the autogenerated stub
    }

 3.数据库操作的save()方法,如果在save()方法前面有使用getByxxx()或者find()这些方法的话,一定要记得给save()方法手动传$data数据。或者连贯操作->data($data)->save(),否则当前要添加或保存的数据会变成刚刚查询到的。查看源码可知道原因:

 

  解决办法:

  //更新失败,因为save()的数据是旧数据
  $Model->create($data); 
  $oldData = $Model->getById($data['id']);
  $updateRes = $Model->save();


   //更新成功
  $Model->create($data); 
  $oldData = $Model->getById($data['id']);
  $updateRes = $Model->save($data);//或者用下面那一行
  //$updateRes = $Model->data($data)->save();

 4、字段缓存问题

  首先是数据库表设计更新以后会有所影响;此外还有个问题,由于我的项目有多个模块,恰好两个模块中有两个模型名都一样,经常出现其中一个模块不能正常添加和修改的情况

后来看了源码才找到原因:字段缓存的文件名是"数据库名+表前缀+模型名",导致两个模型读取的缓存文件名是一样的

  

解决办法:

(1)关闭字段缓存 

(2)不同模块设置不同的表前缀

(3)修改模型的名称

 

个人觉得TP框架的这个缓存机制实在不太合理,模型里面明明都有指定tableName,没必要根据表前缀和模型名去缓存字段

5、S()方法缓存失败

在命令行模式下,执行定时脚本发现S()方法缓存失败,首先想到的就是权限问题,但是检查以后还是不行,后来一步步找到源码,发现缓存文件的路径是C('DATA_CACHE_PATH'),由于APP_PATH是相对路径,导致这个也是相对路径

然而,用crontab执行php脚本,代码里面一定要用绝对路径,否则很容易出错。把APP_PATH设置为__DIR__.'/Application/',问题解决

6、这条不是坑,是个小提示

我们在添加数据时,有时候希望如果已经存在了就更新,通常会用ON DUPLICATE KEY UPDATE语句,之前一直以为thinkPHP没有这个方法,只能通过自己手动拼接sql语句。

这几天看了一下Mysql.class.php的源码发现是支持的,只是官方文档没有给出来。

$addRes = $Model->add($addData,array(),'cpu,mem,hard_disk');

通常我们只会传第一个参数,第二个参数是配置,默认是空数组,第三个参数就是ON DUPLICATE KEY UPDATE要更新的字段。支持字符串和数组的形式。对于addAll()方法也是一样的。

 

 

 

  

 

posted @ 2017-10-30 09:23  小昌君  阅读(685)  评论(0编辑  收藏  举报