understanding the load_class in CodeIgniter

2019-07-07 07:15发布

问题:

im trying to understand the framework structure in CodeIgniter and i have just started and came up with this little misunderstanding .

so can somebody please help me under stand the following :-

1- why do they use a reference to pass an instance of the class ... i mean why not just a simple variable ?

2- and why does the function store the name of the class in an array instead of a "string variable" (please dont judge my php terms as im the worst at it ).. ?!

static $_classes = array();
                   ^^^^^^^ this cloud be just ("") or am i missing something

here is the function so you wont go looking for it .

function &load_class($class, $directory = 'libraries', $prefix = 'CI_')
    {
        static $_classes = array();

        // Does the class exist?  If so, we're done...
        if (isset($_classes[$class]))
        {
            return $_classes[$class];
        }

        $name = FALSE;

        // Look for the class first in the local application/libraries folder
        // then in the native system/libraries folder
        foreach (array(APPPATH, BASEPATH) as $path)
        {
            if (file_exists($path.$directory.'/'.$class.'.php'))
            {
                $name = $prefix.$class;

                if (class_exists($name) === FALSE)
                {
                    require($path.$directory.'/'.$class.'.php');
                }

                break;
            }
        }

        // Is the request a class extension?  If so we load it too
        if (file_exists(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.'.php'))
        {
            $name = config_item('subclass_prefix').$class;

            if (class_exists($name) === FALSE)
            {
                require(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.'.php');
            }
        }

        // Did we find the class?
        if ($name === FALSE)
        {
            // Note: We use exit() rather then show_error() in order to avoid a
            // self-referencing loop with the Excptions class
            exit('Unable to locate the specified class: '.$class.'.php');
        }

        // Keep track of what we just loaded
        is_loaded($class);

        $_classes[$class] = new $name();
        return $_classes[$class];
    }

回答1:

The key is the static keyword before $_classes = array();. This makes the $_classes array hold it's value in between multiple calls to the function. Basically they use it as a local cache for the instantiated classes. For this purpose a string won't work.

See more about the static keyword in the manual.

As for the reference returning, i think that's php4 baggage, CI was supported on php4 until 2.x. You might find this blogpost helpful to see what was changed from php4 to php5.



回答2:

Passing a normal (non-reference) variable 'seems' to work because every time you pass it, the previous instance is overwritten and the last or the newest instance takes the place. So every time you are creating a new class instance. But that is wasteful for 2 reasons...

  1. It creates a new instance variable, without unsetting the previous one (though PHP will garbage collect those eventually), thereby keeping alive a risk of being read by some malicious code and wasting a few bytes in your precious server space for which you have to pay for.

  2. An instance means a state. A state of 'inputs', a state of 'security', a state of 'configuration' and so on. If you create a new variable you are creating a copy of those states. If you then make any mistake by chance, then your current state held in one 'Input' instance may not be changed to reflect the current or latest state. Suppose the other one has changed; If you use both of them in different occasions then that may lead to a conflict and a disaster in the next step.