【问题标题】:Codeigniter - Load Library Class in a LibraryCodeigniter - 在库中加载库类
【发布时间】:2014-03-05 21:04:12
【问题描述】:

我的应用程序适用于第三方应用程序。第三方应用是一个库类,位于application/libraries/NAMEOFTHECLASS/main.php

我有一个模块处理程序库,它负责处理第三方类。

第三方类如下所示:

 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;
}
}

在模块处理程序中,我将我需要的每个第三方类加载到一个 foreach 中并调用一个函数。

我的 ModuleHandler 类中的 Zb 是从第三方脚本获取表单元素的方法:

    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;
    } 

问题是,每个第三方类都有 main 的名称。我得到了我不能重新声明主类的错误。 有没有办法取消设置加载的类?

我已经用 unset 试过了。但它不起作用。

【问题讨论】:

  • 为什么不直接切换/case $type 并从同一个文件夹中加载具有不同名称但具有相同界面(策略模式)的类?工作量很小,而且比摆弄 CI 内部类更干净。

标签: php codeigniter codeigniter-2


【解决方案1】:

您可以使用一个小技巧来卸载库,为此您必须扩展 Loader

在 appilication/core/MY_Loader 中创建一个文件MY 是来自$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);
        }
    }
}

}

现在您可以使用

卸载库
$this->load->unload_library('YOUR_LIB_NAME');

【讨论】:

  • 感谢您的回复。我创建了新的加载程序类,但如果我在 foreach 中运行此代码:$class = 'thirdparty/cm_system/'.$type.'/main'; $this->CI->load->library($class); $this->CI->main->init($config); $form_elements = $this->CI->main->getFormElements($value); array_push($form_data, $form_elements); $this->CI->load->unload_library("main"); 我收到此错误致命错误:无法在第 10 行的库/第三方/reg_input/main.php 中重新声明主类谢谢
  • 编辑:我测试了以下代码:$class = 'thirdparty/cm_system/'.$type.'/main'; $this->CI->load->library($class); $this->CI->main->init($config); $form_elements = $this->CI->main->getFormElements($value); array_push($form_data, $form_elements); $this->CI->load->unload_library("main"); $this->CI->main->getFormElements($value); 卸载后出现错误。那个 main 不是一个对象,这是正确的。但我也得到与顶部相同的错误谢谢
  • 是的,你是对的,我的代码只会 __destruct 对象,但 php 已经加载了文件,所以你不能再次声明相同的名称,我用我的代码重新加载了 lib,但你的情况没办法:(
【解决方案2】:

你可以这样做:

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

如果您导航到/ci/system/core/loader.php,您会在第 194 行找到public function library()

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

第三个参数允许您指定唯一的对象名称以避免冲突。

所以现在你可以简单地调用:

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

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

【讨论】:

  • 感谢您的回复。如果我使用此代码运行该函数:$class = 'thirdparty/cm_system/'.$type.'/main'; $this->CI->load->library($class, null, $type); $this->CI->$type->init($config); $form_elements = $this->CI->$type->getFormElements($value); array_push($form_data, $form_elements); unset($this->CI->$type); 我收到此错误:致命错误:无法在第 10 行的 /libraries/thirdparty/reg_input/main.php 中重新声明类 main 谢谢
【解决方案3】:

由于 CI 不使用命名空间,因此无法按原样进行。

这不是 CI 限制,而是 PHP 限制。 CI include 文件,所以如果你包含两个带有class Main 的文件,它当然会崩溃。

最简单和最干净的解决方案是将您的类和关联文件命名为与文件夹相同的名称。

即:

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

将“主”类与文件夹命名相同是很常见的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-27
    • 2015-07-16
    • 2011-06-14
    • 2015-12-10
    • 2015-06-08
    相关资源
    最近更新 更多