挑战性问题:在Code Igniter中从外部目录加载模型

时间:2013-10-31 15:26:20

标签: php codeigniter configuration model

我一直试图找出一种方法来加载来自" application / models"以外的不同目录的模型。目录。 我想从" application / modules"。

加载我的模型

我已按照

中提供的说明扩展CI_Loader,尝试了这些说明

http://ellislab.com/forums/viewthread/103276/#

但它给了我错误"无法找到指定的类:Model.php"而我的核心" Model.php"是"系统/核心"文件夹中。

甚至,我也尝试使用

加载模型
 $this->load->model (APPPATH.'modules/mymodel.php');

但没有成功。

更新

我希望我的模型加载器的行为如下:

$this->load->module('mymodel') 

$ this-> mymodel-> mymodelmethod()!!

NOT like:    $this->load->models('mymodel') 

有什么方法可以从"application/modules"文件夹之外加载模型吗? 请指教。谢谢

4 个答案:

答案 0 :(得分:2)

问题是 the code you reference 适用于较旧版本的codeigniter。在旧版本的codeigniter中,CI_Model类名为Model。由于最新版本的php中不存在类Model,您将收到错误:

Unable to locate the specified class: Model.php

发生这种情况的代码部分即将结束(第114行):

    if ( ! class_exists('Model'))
    {
        load_class('Model', FALSE);
    }

如果你检查你的system / core / Loader.php,你会发现你使用的codeigniter版本已被替换为:

    if ( ! class_exists('CI_Model'))
    {
        load_class('Model', 'core');
    }

您需要重新编写MY_Loader.php,使其与您正在使用的codeigniter版本兼容,大概是2.1。

最好的方法是抓住 Codeigniter 2.1 version of the core Loader.php 并使用model()方法作为重写MY_Loader.php的基础。< / p>

重写MY_Loader.php时要记住的一点是构造函数在更高版本的codeigniter中也发生了变化,所以你的MY_Loader类看起来应该是这样的:

class MY_Loader extends CI_Loader {

    function __construct()
    {
        parent::__construct();
    }

    public function model($model, $name = '', $db_conn = FALSE)
    {
        ...
    }
}

有关扩展核心类的更多详细信息,请参阅 Codeigniter Documentation


<强>更新

我注意到你改变了你的功能,所以我更新了答案。您可以创建一个全新的加载器并将其基于核心CI_Model类,尽管在扩展模型加载器并完成时似乎需要付出很多努力。

class MY_Loader extends CI_Loader {

    protected $_ci_module_paths     = array();
    protected $_ci_modules          = array();

    function __construct()
    {
        parent::__construct();

        $this->_ci_module_paths = array(APPPATH);
    }

    public function initialize()
    {
        $this->_ci_classes = array();
        $this->_ci_loaded_files = array();
        $this->_ci_models = array();
        $this->_ci_modules = array();
        $this->_base_classes =& is_loaded();

        $this->_ci_autoloader();

        return $this;
    }

    public function module($module, $name = '', $db_conn = FALSE)
    {
            if (is_array($module))
            {
                    foreach ($module as $babe)
                    {
                            $this->$module($babe);
                    }
                    return;
            }

            if ($module == '')
            {
                    return;
            }

            $path = '';

            // Is the $module in a sub-folder? If so, parse out the filename and path.
            if (($last_slash = strrpos($module, '/')) !== FALSE)
            {
                    // The path is in front of the last slash
                    $path = substr($module, 0, $last_slash + 1);

                    // And the module name behind it
                    $module = substr($module, $last_slash + 1);
            }

            if ($name == '')
            {
                    $name = $module;
            }

            if (in_array($name, $this->_ci_modules, TRUE))
            {
                    return;
            }

            $CI =& get_instance();
            if (isset($CI->$name))
            {
                    show_error('The module name you are loading is the name of a resource that is already being used: '.$name);
            }

            $module = strtolower($module);

            foreach ($this->_ci_module_paths as $mod_path)
            {
                    if ( ! file_exists($mod_path.'modules/'.$path.$module.'.php'))
                    {
                            continue;
                    }

                    if ($db_conn !== FALSE AND ! class_exists('CI_DB'))
                    {
                            if ($db_conn === TRUE)
                            {
                                    $db_conn = '';
                            }

                            $CI->load->database($db_conn, FALSE, TRUE);
                    }

                    if ( ! class_exists('CI_Model'))
                    {
                            load_class('Model', 'core');
                    }

                    require_once($mod_path.'modules/'.$path.$module.'.php');

                    $module = ucfirst($module);

                    $CI->$name = new $module();

                    $this->_ci_modules[] = $name;
                    return;
            }

            // couldn't find the model
            show_error('Unable to locate the module you have specified: '.$module);
    }


    public function add_package_path($path, $view_cascade=TRUE)
    {
        $path = rtrim($path, '/').'/';

        array_unshift($this->_ci_library_paths, $path);
        array_unshift($this->_ci_model_paths, $path);
        array_unshift($this->_ci_module_paths, $path);
        array_unshift($this->_ci_helper_paths, $path);

        $this->_ci_view_paths = array($path.'views/' => $view_cascade) + $this->_ci_view_paths;

        // Add config file path
        $config =& $this->_ci_get_component('config');
        array_unshift($config->_config_paths, $path);
    }

    public function remove_package_path($path = '', $remove_config_path = TRUE)
    {
        $config =& $this->_ci_get_component('config');

        if ($path == '')
        {
            $void = array_shift($this->_ci_library_paths);
            $void = array_shift($this->_ci_model_paths);
            $void = array_shift($this->_ci_module_paths);
            $void = array_shift($this->_ci_helper_paths);
            $void = array_shift($this->_ci_view_paths);
            $void = array_shift($config->_config_paths);
        }
        else
        {
            $path = rtrim($path, '/').'/';
            foreach (array('_ci_library_paths', '_ci_model_paths', '_ci_module_paths', '_ci_helper_paths') as $var)
            {
                if (($key = array_search($path, $this->{$var})) !== FALSE)
                {
                    unset($this->{$var}[$key]);
                }
            }

            if (isset($this->_ci_view_paths[$path.'views/']))
            {
                unset($this->_ci_view_paths[$path.'views/']);
            }

            if (($key = array_search($path, $config->_config_paths)) !== FALSE)
            {
                unset($config->_config_paths[$key]);
            }
        }

        // make sure the application default paths are still in the array
        $this->_ci_library_paths = array_unique(array_merge($this->_ci_library_paths, array(APPPATH, BASEPATH)));
        $this->_ci_helper_paths = array_unique(array_merge($this->_ci_helper_paths, array(APPPATH, BASEPATH)));
        $this->_ci_model_paths = array_unique(array_merge($this->_ci_model_paths, array(APPPATH)));
        $this->_ci_module_paths = array_unique(array_merge($this->_ci_module_paths, array(APPPATH)));
        $this->_ci_view_paths = array_merge($this->_ci_view_paths, array(APPPATH.'views/' => TRUE));
        $config->_config_paths = array_unique(array_merge($config->_config_paths, array(APPPATH)));
    }

    private function _ci_autoloader()
    {
        if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/autoload.php'))
        {
            include(APPPATH.'config/'.ENVIRONMENT.'/autoload.php');
        }
        else
        {
            include(APPPATH.'config/autoload.php');
        }

        if ( ! isset($autoload))
        {
            return FALSE;
        }

        // Autoload packages
        if (isset($autoload['packages']))
        {
            foreach ($autoload['packages'] as $package_path)
            {
                $this->add_package_path($package_path);
            }
        }

        // Load any custom config file
        if (count($autoload['config']) > 0)
        {
            $CI =& get_instance();
            foreach ($autoload['config'] as $key => $val)
            {
                $CI->config->load($val);
            }
        }

        // Autoload helpers and languages
        foreach (array('helper', 'language') as $type)
        {
            if (isset($autoload[$type]) AND count($autoload[$type]) > 0)
            {
                $this->$type($autoload[$type]);
            }
        }

        // A little tweak to remain backward compatible
        // The $autoload['core'] item was deprecated
        if ( ! isset($autoload['libraries']) AND isset($autoload['core']))
        {
            $autoload['libraries'] = $autoload['core'];
        }

        // Load libraries
        if (isset($autoload['libraries']) AND count($autoload['libraries']) > 0)
        {
            // Load the database driver.
            if (in_array('database', $autoload['libraries']))
            {
                $this->database();
                $autoload['libraries'] = array_diff($autoload['libraries'], array('database'));
            }

            // Load all other libraries
            foreach ($autoload['libraries'] as $item)
            {
                $this->library($item);
            }
        }

        // Autoload models
        if (isset($autoload['model']))
        {
            $this->model($autoload['model']);
        }

        // Autoload modules
        if (isset($autoload['module']))
        {
            $this->module($autoload['module']);
        }
    }

}

您可以通过以下方式在控制器中使用上述内容:

$this->load->module('test_module');
$this->test_module->method();

答案 1 :(得分:1)

如果我正确地解决了您的问题,您必须初始化CI的实例。

示例: -

在外部文件中执行以下操作: -

    class modules
    {
        var $CI;

        function __construct()
        {
            $this->CI =& get_instance();
        }

        function retrieve_data()
        {
          // Load Model
          $this->CI->load->model('YOUR MODEL NAME'); // Give the name of your model that you want to laod
        }
     }

希望它可以帮助你:)

答案 2 :(得分:0)

据我所知,你的问题的答案就在这里。

Moduler Extension

下载并按照说明安装。那么你可以通过这些步骤简单地访问任何东西。

在您的控制器中加载模块,如下所示。

$this->load->module('pages');

确保您有一个目录Modules正在申请中。你的模块pages应该存在于那里。 Pages module可以包含控制器,模型,视图,帮助程序,配置和库等。

现在你需要打电话给模特。这是你如何做到的。

$this->pages->model->test_model->get_test_data();

另外,您应该注意加载模块加载所有资源。

答案 3 :(得分:0)

如果无效,请尝试此

public function setPackagePaths($path, $view_cascade=TRUE, $model_cascade=TRUE, $library_cascade=TRUE, $helper_cascade=TRUE) { 
        $path = rtrim($path, '/').'/';

        ///$this->_ci_view_paths = $this->_ci_library_paths = $this->_ci_model_paths = array();
        $this->_ci_library_paths = array($path.'libraries/' => $library_cascade) + $this->_ci_library_paths ;
        $this->_ci_helper_paths = array($path.'helpers/' => $helper_cascade) + $this->_ci_helper_paths ;
        $this->_ci_model_paths = array($path.'models/' => $model_cascade) + $this->_ci_model_paths ;
        $this->_ci_view_paths = array($path.'views/' => $view_cascade) + $this->_ci_view_paths;



        // Add config file path
        $config =& $this->_ci_get_component('config');
        array_unshift($config->_config_paths, $path);
    }

将此功能更新为Loader Class是一种硬核方式。但工作正常。