在php中重构事务处理代码


refactor transaction handling code in php

我正在使用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,因此您将无法在闭包中访问它,因此您需要传递它的副本。