CodeIgniter Forums

Full Version: CodeIgniter: How can I create a new instance of a library whenever the method is called?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.

El Forum

[eluser]mrking[/eluser]
just some snippet of the code

Code:
function __construct() {
   $this->ci = &get;_instance();
   ...
   ...
}

function run() {
   foreach($run_2_time as $run){ $this->deduct_user_point(); ... ... }
}

function deduct_user_point() {  
   $this->ci->load->library('user_lib');
   ...
   ...
}

Firstly, i know that by executing $this->ci->load->library, it will create an object of the class but will subsequent call by the foreach loop in run() create a new object. My thought is no, but someone please verify.

And yes, I do know of one other alternative, which is to insert a third parameter into $this->ci->load->library which is unique for every loop,

Code:
$this->ci->load->library('user_lib','',$class_name);

and that might solve the problem, but is that the only solution?

El Forum

[eluser]pistolPete[/eluser]
Why do you want new instances at all?
You can still use traditional php:
Code:
require(APPPATH.'libraries/userlib.php');
$user = new Userlib();
...

El Forum

[eluser]mrking[/eluser]
Actually it would be easier if i show the whole snippet of code which i will after I tidy it up.

Btw, whats your view on the query below.

Quote:Firstly, i know that by executing $this->ci->load->library, it will create an object of the class but will subsequent call by the foreach loop in run() create a new object. My thought is no, but someone please verify.

El Forum

[eluser]pistolPete[/eluser]
Have a look at the loader class, it's pretty self-explanatory:
Code:
/* Location: ./system/libraries/Loader.php */
/* line 767 and following */      
          
                 // Safety:  Was the class already loaded by a previous call?
                if (in_array($filepath, $this->_ci_loaded_files))
                {
                    // Before we deem this to be a duplicate request, let's see
                    // if a custom object name is being supplied.  If so, we'll
                    // return a new instance of the object
                    if ( ! is_null($object_name))
                    {
                        $CI =& get_instance();
                        if ( ! isset($CI->$object_name))
                        {
                            return $this->_ci_init_class($class, '', $params, $object_name);
                        }
                    }
                
                    $is_duplicate = TRUE;
                    log_message('debug', $class." class already loaded. Second attempt ignored.");
                    return;
                }

--> If you don't use the third parameter, no new instances will be created.

El Forum

[eluser]mrking[/eluser]
ok as mention, my code below. please note that im still new to this, so will be happy to receive any feedback/recommended best practice.


Code:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

class Checkout_lib {
    var $error = array();
    var $checkout_id = ''; //initialise once run() is called
    var $total_amount_payable = 0;
    var $type_of_delivery = 'N';
    var $payment_status = '';

    function Checkout_lib($param = array()) {
        $this->ci =& get_instance(); //to grab CI object and insert into this current object so that we can use the CI framework resources, eg. helper etc.
        
        if (count($param) > 0) {
            $this->initialize($param);
        }
    }

    function initialize($param = array()) {
        if(count($param) > 0) { //initialise the parameters
            foreach ($param as $key => $val) {

                switch ($key) { // for the option array in the product array
                    case "options":
                    
                        foreach($val as $option => $val) {
                            $this->$option = $val;
                        }
                        break;
                        
                    case "id": //rename id variable to product_id
                    
                        $this->product_id = $val;
                        break;
                        
                    default: //for the other normal product info such as id, qty, price etc.
                        $this->$key = $val;
                }
            }
        } else {
                log_message('debug', 'Checkout_lib param failed to initialized.');
                exit;
        }
    }
    
    
    function run() {
        foreach($this->checkout_product as $product) {
            $this->initialize($product);
            
            $this->total_amount_payable += $this->price;
            
            if($this->deduct_user_point()
            ) {
                log_message('debug',$this->username.' - '.$this->checkout_id.' - '.$this->product_id.' processed.');
            } else {
                return FALSE;
            }
        }
        if($this->record_payment()) $this->ci->cart->destroy(); else return FALSE;
        return TRUE;
    }
            
    function deduct_user_point() {  //need a new class name for CI to create new instance of object whenever it is called, by default we will use the original file name/class name
        
        $class_name = (isset($this->rowid) ? 'user_lib'.$this->rowid : 'user_lib'); //as we need a unique class name for every call from each product, we will prefix user_lib with $this->rowid to be used as the new class name

        $this->ci->load->library('user_lib',array('username'=>$this->username),$class_name);
        
        $point_to_update =  $this->ci->$class_name->user_info->point - $this->point; //deduct point
        
        if($this->ci->$class_name->update_user_info(array('point'=>$point_to_update))) {
            return TRUE; //point deducted successfully
        } else {
            $this->error['checkout_error'][] = $this->ci->lang->line('error_checkout') .
                                                            $this->ci->lang->line('error_deduct_user_point') .
                                                            $this->ci->lang->line('error_checkout_reference_no') . $this->checkout_id;    
            return FALSE;
        }
    }
}

El Forum

[eluser]mrking[/eluser]
Code:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

class User_lib {

    function User_lib($param = array()) {
        $this->ci =& get_instance(); //to grab CI object and insert into this current object so that we can use the CI framework resources, eg. helper etc.
        
        if (count($param) > 0) {//$params[0] - because[0] is the object that contains the array of information, print_r($param)
            $this->initialize($param);
        }
        
        log_message('debug', 'Review_lib class initialized');
    }
    
    function initialize($param = array()) {
        if(count($param) > 0) { //initialise the parameters
            //initialise the class parameters
            foreach ($param as $key => $val) {
                $this->$key = $val;
            }
            
            //initialise the field in db to become local variable
            $this->user_info = $this->user_info();
            
        } else {
                log_message('debug', 'User_lib param failed to initialized.');
                exit;
        }
    }
    
    function user_info() {
        $this->ci->load->model('user/user_model');

        if($user_info = $this->ci->user_model->user_info($this->username)) { //username exist and array containing all user info is returned
            return $user_info; //returns an object from user_model as result will be a single row
        } else { //product id not found, redirect to gallery
                log_message('debug', 'username not found');
                return FALSE;
        }
    }
}

this is the edited one where each call from the loop creates a new instance.

so the logic is this, there are 2 products(contain in an array) by 1 user. so, foreach each product, so some processing, return some result and eventually deduct point from user.

so the first loop execution of

Code:
$point_to_update =  $this->ci->[b]user_lib[/b]->user_info->point - $this->point; //deduct point

got no problem, but once it reach the second loop execution of the same code,

Code:
$this->ci->[b]user_lib[/b]->user_info->point

seems not to be updated from the deduction of the first loop.