codeigniter 2.1 $this->CI contains $CI variables continuously - php

$this->CI has $CI ($this->CI->CI)
And $this->CI->CI has $CI ($this->CI->CI->CI)
And $this->CI->CI->CI has $CI ($this->CI->CI->CI->CI)
And $this->CI->CI->CI->CI has $CI ($this->CI->CI->CI->CI->CI)
.....
......
$CI($this->CI->CI) has same keys and values with $this->CI (See following screenshot)
Image description
I can't determine how many $this->CI had $CI.
Why does $this->CI has $CI continuously?
Please tell me what the cause, what did I do something wrong?

There is no problem. $CI and $this are essentially the same memory location. The variables listing recusively lists the same memory structure again and again. The only way you will run out of memory is if you keep drilling down into the list and the debugger uses it all. In other words, what you a seeing is an illusion.

Related

Can not access to codeigniter superobject into the hooks and uri

I first call a super object and add this contractor
$this->CI =& get_instance();
but when I want to access
print_r($this->CI->router->fetch_class());
it shows the error
Trying to get property of non-object

CodeIgniter Error using Memcached inside cURL

I'm getting an error when trying to use memcached inside a cURl write function inside Codeigniter.
curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($ch, $str)
{ //print(htmlentities($str)."\n\n");
$ci &= get_instance();
$ci->cache->memcached->save('foo', 'bar', 600); return strlen($str);
});
The errors are
Message: Undefined variable: ci
Message: Object of class admin_test could not be converted to int
Any suggestions?
I tried the advice from this link CodeIgniter: can't access $this within function in view
and from here:
Object of class stdClass could not be converted to string
I can use the $ci syntax to make a database query like this
$ci->db->query('SELECT * FROM TABLE');
but not with memcached.
I figured it out, not nearly as hard as I thought.
I was using
$ci &= get_instance();
But what I needed was
$ci = get_instance();

codeigniter library within library issue

I am trying to call libraryA within libraryB in the constructor of the libraryB.
I am aware I can do:
$CI =& get_instance();
$CI->load->library('A');
$CI->A->someFunc()
However I cannot call $CI->A->someFunc() without initiating it with
$CI =& get_instance(); $CI->load->library('A'); in whatever function in B I am trying to access someFunc();. In other situations I would just be able to initiate it in the constructor $this->load->model('somemodel'); and call the model in any function within the class with $this->load->someFunc();. How to I achieve the same functionality without having to rewrite the block of code above over and over in each function I want to use it?
I'm not 100% clear this is what you're asking (your question is confusing), but you can save the CI instance as a property, then access it from anywhere in your class.
class My_library {
protected $CI;
public function __construct()
{
$this->CI =& get_instance();
$this->CI->load->library('other_library');
}
public function someMethod()
{
// Use the library (and the CI object) via the CI property.
$var = $this->CI->other_library->anotherMethod();
}
}

CodeIgniter issue with database library

I am trying to build a custom library of a Shopping Cart. I had some issues with loading the database library into the Cart class but I solved that with using:
$CI =$ get_instance();
$CI->load->database();
But now whenever I want to use the database library it gives me the error: "Trying to get property of non-object" on this line:
$this->CI->db->insert("carts", $data);
I should mention that I declared the $CI variable at the top of my class like this:
var $CI;
Any help would be appreciated!
Thanks in advance.
If $CI is a class variable, as you say it is, then you'll need to use
$this->CI =& get_instance();
$this->CI->load->database();
instead of
$CI =& get_instance();
$CI->load->database();
initialize $this->CI in constructor to make available in every methods.

get_instance() in Codeigniter: Why assign it to a variable?

In Codeigniter, get_instance() is a globally available function that returns the Controller super-object which contains all the currently loaded classes (it returns the Controller class instance). I'll include the current source code:
get_instance() is defined in Codeigniter.php
// Load the base controller class
require BASEPATH.'core/Controller.php';
function &get_instance()
{
return CI_Controller::get_instance();
}
And CI_Controller is defined in Controller.php
class CI_Controller {
private static $instance;
/**
* Constructor
*/
public function __construct()
{
self::$instance =& $this;
// Assign all the class objects that were instantiated by the
// bootstrap file (CodeIgniter.php) to local class variables
// so that CI can run as one big super object.
foreach (is_loaded() as $var => $class)
{
$this->$var =& load_class($class);
}
$this->load =& load_class('Loader', 'core');
$this->load->set_base_classes()->ci_autoloader();
log_message('debug', "Controller Class Initialized");
}
public static function &get_instance()
{
return self::$instance;
}
}
Here's how it is recommended to be used in the user guide for creating libraries:
Utilizing CodeIgniter Resources within Your Library
To access CodeIgniter's native resources within your library use the
get_instance() function. This function returns the CodeIgniter super
object.
Normally from within your controller functions you will call any of
the available CodeIgniter functions using the $this construct:
$this->load->helper('url'); $this->load->library('session');
$this->config->item('base_url'); etc.
$this, however, only works directly within your controllers, your
models, or your views. If you would like to use CodeIgniter's classes
from within your own custom classes you can do so as follows:
First, assign the CodeIgniter object to a variable:
$CI =& get_instance();
Once you've assigned the object to a variable, you'll use that
variable instead of $this:
$CI =& get_instance();
$CI->load->helper('url'); $CI->load->library('session');
$CI->config->item('base_url'); etc.
Note: You'll notice that the above get_instance() function is being
passed by reference:
$CI =& get_instance();
This is very important. Assigning by reference allows you to use the
original CodeIgniter object rather than creating a copy of it.
Related posts: explain $CI =& get_instance(); / Codeigniter: Get Instance
So, here is my actual question:
Why does the user guide recommend assigning get_instance() to a variable? I'm fairly certain I understand the implications of not assigning by reference, but why is it recommended to assign it to a variable when get_instance()->load->model() works fine?
I see a lot of user defined or third party classes in CI that assign to a property of the object:
class MY_Class {
private $CI;
function __construct()
{
$this->CI =& get_instance();
}
function my_func()
{
$this->CI->load->view('some_view');
}
function my_other_func()
{
$this->CI->load->model('some_model');
}
}
Poor example, but I see this frequently. Why bother with this method instead of just calling get_instance() directly? It seems like assigning the entire Controller object to a class variable wouldn't be a great idea, even if it is a reference. Maybe it doesn't matter.
I want to write a wrapper function for get_instance() so it's easier to type, and I don't have to constantly assign it to a variable.
function CI()
{
return get_instance();
}
Or:
function CI()
{
$CI =& get_instance();
return $CI;
}
Then I could use CI()->class->method() from anywhere without the hassle of assigning it to a variable, it's very easy to write and understand what it does, and can result in shorter, more elegant code.
Is there any reason not to take this approach?
Is there any difference between the two CI() functions above?
Why is it recommended to assign get_instance() to a variable rather than calling it directly?
What does the & in function &get_instance(){} mean where it is defined? I know a bit about what references are for and I use them when appropriate, but I've never seen a function defined this way. If I do write a wrapper function, should I use this as well?
Please note that this is not so much a style question, but a technical one. I want to know if there are any issues, performance or otherwise, with using the method I'm suggesting.
EDIT: So far we have:
Method chaining is not available in php4, so assigning to a variable is a workaround (although this is fairly irrelevant as Codeigniter has dropped php4 support)
The minor overhead of calling a function more than once to return the object, rather than calling it once and assigning to a variable.
Anything else, or are these the only potential issues?
As far as I know, it's a matter of convenience more than anything. Chances are that you will be using the CI super object a lot in your libraries so why not assign it to a variable to make it a little easier to work with?
There are a few other things to consider...
If you put this method in a helper, that method becomes a dependency for any class you are using it in. This might not be a big deal for you, but if you want to share libraries with anyone else they may not be happy about the dependency, especially since there is already a standard way of handling this in the CI community.
There is a slight impact on performance because you are calling get_instance() every time you use the helper rather than storing its result in a variable.
Since this is a helper method that is supposed to save you time, for anyone who is working mostly in the core MVC files of CI, setting up a helper like this would take longer than just setting it to a variable in the few places you need it.
Why is it recommended to assign get_instance() to a variable rather
than calling it directly?
Most probably, it is recommended to maintain backward compatibility with php4, where objects were not passed by reference by default, but were cloned.
Is there any reason not to take this approach?
Only if you want your application to run on outdated php installations
It is necessary to assign by reference because the value of CI_Controller::$instance is subject to change if another instance of the class is created. The constructor re-assigns self::$instance each time it runs.
In general, this feels like a bad design pattern and is missing the property of a singleton that limits the class to only one instance, http://en.wikipedia.org/wiki/Singleton_pattern.
It seems possible to type, CI_Controller::get_instance()->$className->$method(); which does seem like more typing that your requested CI()->$className->$method.
Ultimately, it would make sense to require that only one instance of $instance can be created and then the need for assigning by reference would be eliminated.
Method chaining is not supported in PHP4 and CI dropped support for PHP4 very recently (from version 2.0.0). Also it's easy to write $CI than writing get_instance() every time.
I prefer uses this way, it's simple
class Test
{
//magic method __get, whit this can use $this->load
//instead create a variable ci, then do $this->ci->load, cool :)
public function __get($var)
{
return get_instance()->$var;
}
public function showUrl()
{
$this->load->helper("url");
echo base_url();
}
}
It could be a combination of several things, including the already mentioned:
Backwards compatibility
Convenience
Style Guide
Preferably, I like the idea of this 'recommendation' as being a part of a style guide. Maybe not the official style guide of CI, but still.
Imagine that all third-party scripts for CI implements this recommendation, any developer would be able to quickly determine how these scripts are designed - although this just being a very small part of the script.
Another thing that IMO is important is the mechanics of method chaining - and doing CI()->class->method() wouldn't seem intuitive for me, knowing how the rest of CI works.
Getting the result of get_instance() by reference just makes no sense since PHP5. Sadly this bad habit seems to be deep-rooted, so let's just deal with it.
For those interested, here's an über fast instance getter:
function CI()
{
static $CI;
isset($CI) || $CI = CI_Controller::get_instance();
return $CI;
}
Note that the static variable wouldn't work if it were assigned by reference.
Also, you are forced not to get by reference the result of this CI(). Extra sugar :-)
Ah, and obviously you still have the (slight) cost of the function call. You still may want to use a variable instead of calling the function dozens of times.

Categories