我正在使用php 5.3.3,并使用codeigniter开发一个MVC Web应用程序。我试图重构的代码基本上是一堆:
$this->db->trans_start();
// do some db updates
$this->db->update(...);
$this->db->update(...);
$this->db->trans_complete();
if ( $this->db->trans_status() == FALSE ) {
$this->handle_db_error();
}
所以我在模型类中有一些上面的代码。我想从模型中重构事务处理部分,并保持DRY。
我想我可以像下面这样使用闭包:
// in parent CI_Model class
class MY_Model extends CI_Model {
public function txn_wrap($closure) {
$this->db->trans_start();
$closure();
$this->db->trans_complete();
if ( $this->db->trans_status() == FALSE ) {
$this->handle_db_error();
}
}
// in child model class
class Blog_model extends MY_Model {
protected $_table = 'app_blog';
public function get($id) {
$instance = $this;
$closure = function() use($instance, $id) {
// do some db updates
$instance->db->update($instance->_table, array('title' => 'bla'), array('id' => $id));
};
$this->txn_wrap($closure);
}
这不起作用,给了我"PHP Fatal error: Using $this when not in object context"
。所以我想在5.3中不支持使用$。
现在使用闭包失败了,我还能做什么?
UPDATE:现在我得到了Undefined property: App_Blog::$_table
,其中App_About是调用Blog_mode中的get((函数的控制器。我尝试过function() use($instance, , $instance->_table, $id)
,但php抱怨语法问题。。现在,这个收尾工作似乎并没有给我带来我想象的那么多好处。。
谢谢!
闭包不是子模型类的方法,因此无法访问实例。您需要将其提供给关闭:
$instance = $this;
$table = $this->_table;
$update_db_closure = function() use ($instance, $table) {
// do some db updates
$instance->db->update($table, ...);
$instance->db->update($table, ...);
};
$this->_table
属性是protected
,因此您将无法在闭包中访问它,因此您需要传递它的副本。