I am using php 5.3.3 and developing a MVC webapp using codeigniter. The code I am trying to refactor is basically bunch of:
$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();
}
so I have a few of the above code scatter around in my model classes. I would like to refactor the transaction handling part out of the models and stay DRY.
I thought I could using closure like the following:
// 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);
}
That doesn’t work and gives me "PHP Fatal error: Using $this when not in object context". So I guess using of $this usage is not supported in 5.3.
Now failing of using closure, What else can I do?
UPDATE: now I am getting Undefined property: App_Blog::$_table where App_About is the controller which calls the get() function in Blog_model. I have tried function() use($instance, , $instance->_table, $id) but php complains about the syntax.. Now this closure thing doesn’t appears give me as much benefits as I thought..
thanks!
The closure is not a method of your child model class, so you cannot access the instance. You will need to provide it to the closure:
The
$this->_tableproperty isprotected, thus you won’t be able to access it inside the closure, so you need to pass a copy of it.