I am putting this code in the constructor for a model class, based on teh tutorial for CI, it states that if you put it there, the database connection can be used globally within that class afterwards. For some reason it's not working and the application crashes at that part of the code. My database configuration is fine since when i put it in the controller i'm able to get db info fine.
Are you doing that before or after the parent class's constructor?
public function __construct()
{
// placing it here fails: $this has no `load` property yet.
// $this->load->database(); <!-- NO WAY JOSÉ!
parent::__construct();
// placing it here should work as the parent class has added that property
// during it's own constructor
$this->load->database();
}
On the other hand, you could be even more explicit:
public function __construct()
{
// Doesn't matter where this goes:
// grab the controller directly
$CI =& get_instance(); // & is not strictly necessary, but still...
// force the loader to load the database.
$CI->load->database();
// directly assign it.
$this->db = $CI->db;
// continue on your merry way
parent::__construct();
}
I believe the explicit solution solved a number of problems in a PHP 4 project once, but it is technically overkill.
you dont need to initialize that . better configure it into
application - config - autoload.php file like this
$autoload['libraries'] = array('database');
The line of code to load the database object is:
$this->load->database();
The database object is then referenced with the name db like so:
$this->db->method_name();
As pointed out by the previous post, if you are going to use the database across multiple models, you should have the library autoloaded in your autoload.php config file.
Related
I am using codeigniter 2.1.3
I am trying to load a model from the library. Initially my code in the construct in the library looks like this
$this->CI=& get_instance(); $this->CI->load->database('default')
Then in one of my library methods
when I tried the line below it doesnt work
$this->load->model('model_name')
but when I tried this
$this->CI->load->model('model_name','',TRUE)
it works, anyone can explain what the instance of CI refers to and the 2 extra parameters when loading the model? Thanks in advance.
A library is not necessarily a part of the way CodeIgniter works.
It could be a homemade library, to solve a task that you want done in your CI application.
This means that if you want to use any of CI's helpers, models or other libraries, you need to do this through the CI instance. This is achieved by doing this:
public function __construct()
{
$this->CI =& get_instance();
}
By assigning the instance to your librarys member named CI, all CI related helpers, models and libraries can be loaded through $this->CI. By trying to do it only with $this you are only referring to the current library - not the CI instance.
To load your model correctly, in your library, $this->CI->load->model('model_name'); is enough. The second parameter allows you to access your model through a different object name. The third parameter is not necessary for loading models, but allows you to autoload the database driver.
If you want to access your model through the same member:
$respone = $this->CI->model_name->method();
I have very simple code that you should use to load model in library
<?php
class Custom_lib
{
private $_CI;
public function __construct()
{
$this->_CI = & get_instance();
$this->_CI->load->model('Dynamic_Model','dm');
}
function currentSession()
{
$session = $this->_CI->dm->fetchSingleData('id,session','session',array('is_active'=>1));
return $session;
}
}
I hope this code will help you
You can tell the model loading function to auto-connect by passing TRUE (boolean) via the third parameter, and connectivity settings, as defined in your database config file will be used:
$this->load->model('Model_name', '', TRUE);
You can more about this at the end of the page of this below link.
http://ellislab.com/codeigniter/user-guide/general/models.html
I want to access database functions in extending libraries.
class My_Router extends CI_Router {
public function __construct()
{
parent::__construct();
}
function _set_routing()
{
.....
....
$query=$this->db->get('custome_routes');
$custom_routes=$query->result_array();
....
}
}
I tried below also
$CI =& get_instance();
$query=$CI->db->get('custome_routes');
$custom_routes=$query->result_array();
But it doesn't work.
Help me....
Thanks in advance,
Logan
Unfortunately you can't do that, because the loading order of the framework, and since the routing information is used to decide what controller class to load, and the return value of get_instance() is that controller instance.
You can try using CI's built in class by require ing the system/DB.php and use the DB() function to get an instance of the db class.
public function _set_routing(){
require_once BASEPATH.'database/DB.php';
$db = DB('default', true); // you can set the database.php config's group, or a full DSN string here
$custom_routes = $db->get('custome_routes')->result_array();
}
Or you could make a CI independent db connection in your subclass, for this one "get the full table" query this shouldn't be hard. You should be able to include the CI database config file and use it's values without problems (watch out for environments).
Just load database from instance ( $CI->load->database(); )
$CI =& get_instance();
$CI->load->database();
$query=$CI->db->get('custome_routes');
$custom_routes=$query->result_array();
EDIT: This just work for libraries and does not work for core classes.
I'm having Codeigniter object scope confusion.
Say I load a model in a controller:
$this->load->model('A');
$this->A->loadUser(123); // loads user with ID 123
// output of $this->A now shows user 123
$this->load->model('B');
$this->B->examineUser ();
// output of $this->A now shows user 345
class B extends Model
{
public function examineUser ()
{
$this->load->model('A');
$this->A->loadUser(345); // loads user with ID 345
}
}
I would have thought that $this->A would be different from $this->B->A but they are not. What is the best solution to this issue? It appears the ->load->model('A') in the examineUser () method does nothing because it was loaded in the controller. Then the call to loadUser () inside that method overwrites the stored properties of $this->A. This seems like a bugfest waiting to happen. If I needed global models, I would have use static classes. What I wanted was something scoped pretty much locally to the model object I was in.
Is there a way I can accomplish this but not go way outside of CI's normal way of operating?
Followup/related:
Where do most people put there "->load->model" calls? All at the beginning of a controller action? I figured it would be easier -- though perhaps not excellent programming from a dependency injection perspective -- to load them in the model itself (construct or each method).
Whenever you use the Loader Class ($this->load->), it will load the object into the main CI object. The CI object is the one you keep referring to as $this->. What you've done is load model A twice into the CI object.
Essentially, all object loaded using the Loader class goes into a single global scope. If you need two of the same type, give them different names, as per $this->load->model('A','C'). I don't know of any way around it unless you revert to using bog-standard PHP.
In my team's code, we generally load the models in the controller's constructor, then load the data to send to the view in the function, often _remap().
This is not how the loader works sadly. CodeIgniter implements a singleton pattern, which will check to see if the class is included, instantiated and set to $this->A then will be ignored if loaded again. Even if you are inside a model, $this->A will be referenced to the super-instance via the __get() in class Model. Alis it, or just do:
class B extends Model
{
public function examineUser ()
{
$user = new A;
$user->loadUser(345); // loads user with ID 345
}
}
Here's what I've decided to do, please comment if you have advice:
I've extended the CI Loader class:
<?php
class SSR_Loader extends CI_Loader
{
function __construct()
{
parent::__construct ();
}
/**
* Model Retriever
*
* Written by handerson#executiveboard.com to create and return a model instead of putting it into global $this
*
* Based on original 2.0.2 CI_Loader::model ()
*
*/
function get_model($model)
{
if (empty ($model))
{
return;
}
$name = basename ($model);
if (!in_array($name, $this->_ci_models, TRUE))
{
$this->model ($model);
}
$name = ucfirst($name);
return new $name ();
}
}
Do any CI guru's see a problem with that before I invest time in changing my code a bit to accept the return obj, ala:
// in a controller:
public function test ($user_id=null)
{
$this->_logged_in_user = $this->load->get_model ('/db/users');
$this->_viewed_user = $this->load->get_model ('/db/users');
$this->_logged_in_user->load($this->session->userdata ('user.id'));
$this->_viewed_user->load($user_id);
}
I could also do private $_logged_in_user to make it available in the controller but positively force it to be limited to just the current controller and not spill anywhere else, or I could just do $_logged_in_user = $this->load->get_model ('/db/users'); and limit it to just the current method, which is probably what I'll do more often.
This seems like a pretty straightforward way to "fix" this issue (I say "fix" b/c it's not really a bug, just a way of doing things that I think is a bad idea). Anyone see any flaws?
hi i am using codeigniter , in my controller constructor sometimes i use $this sometimes $this->ci
in two constructors i have use like this
public function __construct()
{
$this->ci =& get_instance();
$this->ci->load->library('form_validation');
$this->ci->load->library('catalog/CatalogManager');
}
function __construct()
{
parent::__construct ();
$this->ci = & get_instance ();
$this->load->library ( 'auth_lib' );
$this->load->library ( 'session' );
}
when passing data to view i use
$this->ci->data and $this->data in above two cases .
neither gives errors , but i am confused , what is the correct use.
please help...........
All controllers extend the main CI_Controller, so calling something like $this->load means accessing the parent method load() inside the parent class CI_Controller.
$this->ci works because with $this->ci = &get_instance() you're calling a reference to the main controller class...again. If you look in the bootstrap file (IIRC. Or the codeigniter.php file) there's the function get_instance(), which does nothing but return (by reference) the instance of the CI_Controller class.
So, basically, calling $this->ci->load and $this->load are the same exact thing, only that the first is unnecessary within a Controller/Model/View because the system is already doing that in the parent class (through the method load).
If you have a look at libraries, for ex., you'll see instead that using $this->ci->method() is necessary, because you need to have available all the methods of the CI_Controller, which is a kind of "super class" that drives the whole framework.
Have a look at the loader class and the CodeIgniter class to grasp how CI internally works.
Agree with the answer above, but actually, load is a variable, not a function. it is a object of the class CI_Loader, when you call $this->load->libray(), in fact it calls the library() function in CI_Loader.
$this is nothing. It just use to store the value. It just like a variable.
I want to generate global variables in CodeIgniter by creating my own library and config file. This is what I wrote ini my library file, let's say globalvars.php. I put it in /application/libraries.
class Globalvars{
function __construct($config = array())
{
foreach ($config as $key => $value) {
$data[$key] = $value;
}
$CI =& get_instance();
$CI->load->library('session');
$CI->load->vars($data);
}
}
I want the user id stored in the session to be available in global variable, so I wrote this in my config file. It's named also globalvars.php. It's in /application/config directory.
$config['user']=$this->session->userdata('id');
I then test to see if it's working by write it in my controller this way.
echo $data['user'];
But I get this error in the browser
Message: Undefined property: CI_Loader::$session
Filename: config/globalvars.php
It seems that the session functions is not defined yet. How can I get it work? What have I missed here? Any help would be appreciated.
You cannot use the session library in config file.
The config files are loaded before any libraries, so $this->session is undefined.
The config.php has to be loaded in order for the Session class to even be initialized, as it reads settings from that file.
A lot of issues with this type of thing (setting some "global" data) can be resolved using a base controller, and extending it in your controllers.
// core/MY_Controller.php
MY_Controller extends CI_Controller {
function __construct()
{
parent::__construct(); // Now the Session class should be loaded
// set config items here
}
}
"Normal" controllers will now extend MY_Controller to take advantage of this.
See: http://codeigniter.com/user_guide/general/core_classes.html for more details.
In addition, when you load->vars(), they are available to the view layer only, it does not create a global variable called $data as you seem to be trying to access. If you do this:
$this->load->vars(array('user' => '1'));
You would access it in a file loaded by $this->load->view() like this:
echo $user; // outputs "1"
See: http://codeigniter.com/user_guide/libraries/loader.html
$this->load->vars($array)
This function takes an associative array as input and generates
variables using the PHP extract function. This function produces the
same result as using the second parameter of the $this->load->view()
function above. The reason you might want to use this function
independently is if you would like to set some global variables in the
constructor of your controller and have them become available in any
view file loaded from any function. You can have multiple calls to
this function. The data get cached and merged into one array for
conversion to variables.
I will say that as an experienced Codeigniter user, the concept of a "global vars" class is a bit wonky and probably unnecessary, especially when it's already so easy to get and set config items. You could definitely run into some confusing issues and variable name conflicts with this method (pre-loading lots of view variables on every request).