Codeigniter - 在库中加载库类

My Application works with Third Party Applications. The Thirdparty Application is a Library Class, which is locaded in application/libraries/NAMEOFTHECLASS/main.php.

I have a Library the modulehandler which has the job to handle the ThirdParty-Classes.

The Third Party Class looks like this:

 class main {

var $name;
var $description;
var $saphir;
var $location;

public function init($config = array()) {
    $this->name = $config['name'];
    $this->description = $config['description'];
    $this->saphir =& get_instance();
    $this->location = $config['location'];
}

public function getFormElements() {
   $html = $this->saphir->load->file($this->location.'/tpl/main.html',true);
   $this->saphir->load->library('parser');

   $data = array(
        'name' => $this->name,
        'description' => $this->description
        );

   $html = $this->saphir->parser->parse_string($html, $data, TRUE);
   return $html;
}

public function validation($post_data)
{
     $array = explode(',', $post_data);
     if($post_data != is_array($array) )
         return array("error" => array("name" => $this->name, "message" => "Bitte geben Sie nur eine Kommagetrennte Liste an"));

}

public function handleData($post_data) {
    $array = explode(',', $post_data);
    $return = array();
    foreach($array as $key => $val) {
        array_push($return, array("data" => $val));
    }
    return $return;
}
}

In the Module Handler i load in a foreach every thirdparty class which i need and call a function.

Zb in my ModuleHandler Class here is the method to get Form Elements from the Thirdparty Scripts:

    private function getForm()
    {

       $form_data = array();
        foreach($this->schema as $schema) {
            $config = array("type" => $schema['type'], "name" => $schema['name'], "description" => $schema['description'], 'location' => 'application/libraries/thirdparty/cm_system/'.$schema['type']);
            $type = $schema['type'];

            if($this->edit) {
                $value = $this->info;
                $val = array();
                foreach($value->ELEMENT as $element)
                {
                    $holder = (string)$element;
                    array_push($val, $holder);
                }
                $value = $val;
            }
            else  {
                $value = "";
            }

            $ins = $this->CI->load->library('thirdparty/cm_system/'.$type.'/main');
            $this->CI->main->init($config);

            $form_elements = $this->CI->main->getFormElements($value); 

            array_push($form_data, $form_elements);

        }
        return $form_data;
    } 

The problem is, that every thirdparty Class has the name main. And i get the error that i cant redeclare class main. Is there a way to unset the loaded class?

I tried it already with unset. But it dont works.

You can do this:

$ins = $this->CI->load->library('thirdparty/cm_system/'.$type.'/main', null, $type);

If you navigate to /ci/system/core/loader.php you will find public function library() on line #194:

public function library($library = '', $params = NULL, $object_name = NULL)

The third parameter allows you to specify a unique object name to avoid collisions.

So now you can simply call:

$this->CI->load->library('thirdparty/cm_system/'.$type.'/main', null, $type);

// and use it like:
$this->$type->someFunction();

You can unload the library using a small hack, to do this you have to extend the Loader

Create a file in appilication/core/MY_Loader MY is the prefix coming from $config['subclass_prefix']

class MY_Loader extends CI_Loader {

public function unload_library($name) {
    $name = strtolower($name);
    foreach ($this->_ci_loaded_files as $key => $path) {
        $file_name = basename($path);
        $value = substr($file_name, 0, strlen($file_name) - 4);
        if (strtolower($name) == strtolower($value)) {
            unset($this->_ci_loaded_files[$key]);
            $CI = & get_instance();
            unset($CI->$name);
        }
    }
}

}

Now you can unload a library using

$this->load->unload_library('YOUR_LIB_NAME');

Since CI does not use namespaces, there is no way to make this work as it is.

It's not a CI limitation, it's a PHP one. CI include the file, so if you include 2 files with a class Main, it will of course crash.

The easiest and cleanest solution is to name your class and the associated file with the same name as the folder.

ie:

$ins = $this->CI->load->library('thirdparty/cm_system/'.$type.'/'.$type);

Having the "main" class named the same as the folder is pretty common.