当我尝试基于它构建自己的框架时,F3的SQL Mapper引发了奇怪的问题。
当我尝试将行插入MySQL数据库时,它会被插入两次。我通过将echo设置为beforeinsert
方法进行了最简单的调试,该方法被触发一次。那么......我做错了什么导致行加倍?
控制器(特定代码):
$faq = new \FaqModel();
$faq->question = $params['q'];
$faq->answer = $params['a'];
$faq->save();
$id = $faq->get('_id');
if (isset($id))
$this->status = 'success'; // this is shown
else
$this->status = 'nope, not working';
FaqModel.php(是的,没有,这里)
class FaqModel extends \BaseModel
{
public function __construct()
{
parent::__construct('faq');
}
}
BaseModel.php(我想到这里,但beforeinsert()
被调用一次):
abstract class BaseModel extends \DB\SQL\Mapper
{
public function __construct($table)
{
$f3 = \Base::instance();
$this->db=new \DB\SQL(
'mysql:host='.$f3->get('db_host').';port='.$f3->get('db_port').';dbname='.$f3->get('db_name'),
$f3->get('db_user'),$f3->get('db_pass'));
parent::__construct($this->db,DB_PREFIX.$table);
$this->table = DB_PREFIX.$table;
$this->beforeinsert(function($me) {
echo 'before insert <br/>';
$me->createdAt = date('Y-m-d H:i:s');
});
echo 'construct <br/>';
}
// some loading methods here not related to problem
}
输出很简单:
construct
before insert
success
并且没有webniffers中显示的重定向。但我仍然得到我的数据库重复行。
好的,现在它比我们更奇怪了。我连续执行了两个添加请求。发生的事情是:
1)在第一次请求时,添加了两行:
41 testing db_testing 2015-02-13 09:08:21 2015-02-13 09:08:21
42 testing db_testing 2015-02-13 09:08:21 2015-02-13 09:08:21
2)在第二次请求时,添加了三个行:
43 testing db_testing 2015-02-13 09:10:53 2015-02-13 09:10:53
44 another_test db_why 2015-02-13 09:11:04 2015-02-13 09:11:04
45 another_test db_why 2015-02-13 09:11:05 2015-02-13 09:11:05
我不知道发生了什么。
答案 0 :(得分:1)
您到此特定控制器的路由怎么样?可能是你在GET请求上这样做了吗?有些浏览器会在实际的GET请求之前发送一个额外的HEAD请求。框架自动处理,调用您的GET控制器,插入行一次,并仅减少对标头的响应。然后是GET请求,它再次执行所有操作,从而产生第二行。这可以解释您的应用行为。
如果是这样,您可以添加一项检查,看看F3 VERB
var是否包含GET
来解决HEAD请求。
答案 1 :(得分:1)
这是一个老问题,但是,fwiw,我怀疑OP的问题是每次保存后都不会发出mapper reset()调用。从技术上讲,我认为映射器对象的行为,如果你没有重置它,是'未定义的',但是有一点意义,映射器会记住最后一条记录,并且有点理解它后面的新记录。
无论如何,F3映射器的最佳实践是实例化新的映射器或在db调用之间发出重置。我不能谈论性能权衡,除了假设reset()无论它做什么都必须比站起来一个全新的对象便宜。
答案 2 :(得分:0)
你应该做的就是在你实例化课程时立即致电reset()
。
最佳做法
parent::__construct($db,'faq')
。在构造之外创建触发器
function addCreated() {
echo 'before insert <br/>';
$this->createdAt = date('Y-m-d H:i:s');
}
将您的触发器添加为$this->beforeinsert([$this,'addCreated']);
完整的基础现在是:
abstract class BaseModel extends \DB\SQL\Mapper
{
public function __construct($table)
{
$f3 = \Base::instance();
$db = $f3->get('db')
parent::__construct($db,DB_PREFIX.$table)
$this->beforeinsert([$this,'addCreated']);
echo 'construct <br/>';
}
// some loading methods here not related to problem
}