0

私はphp 5.3.3を使用しており、codeigniterを使用してMVC webappを開発しています。私がリファクタリングしようとしているコードは、基本的に次のようなものです。

$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"。したがって、$this の使用は 5.3 ではサポートされていないと思います。

クロージャーの使用に失敗しました。他に何ができますか?

更新: App_AboutUndefined property: App_Blog::$_tableは、Blog_model で get() 関数を呼び出すコントローラーです。私は試しfunction() use($instance, , $instance->_table, $id)ましたが、phpは構文について不平を言います..今、このクロージャは私が思ったほど多くの利点を与えてくれません..

ありがとう!

4

1 に答える 1

1

クロージャは子モデル クラスのメソッドではないため、インスタンスにアクセスできません。クロージャーにそれを提供する必要があります:

$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であるため、クロージャー内ではアクセスできないため、そのコピーを渡す必要があります。

于 2012-06-04T11:47:12.347 に答える