public function model($model, $name = '', $db_conn = FALSE)
{
if (empty($model)) {
return $this;
} elseif (is_array($model)) {
foreach ($model as $key => $value) {
is_int($key) ? $this->model($value, '', $db_conn) : $this->model($key, $value, $db_conn);
}
return $this;
}
$path = '';
// Is the model in a sub-folder? If so, parse out the filename and path.
if (($last_slash = strrpos($model, '/')) !== FALSE) {
// The path is in front of the last slash
$path = substr($model, 0, ++$last_slash);
// And the model name behind it
$model = substr($model, $last_slash);
}
if (empty($name)) {
$name = $model;
}
if (in_array($name, $this->_ci_models, TRUE)) {
return $this;
}
$CI =& get_instance();
$model_paths = $this->_ci_model_paths;
if ($this->_ci_is_inside_module) {
$module_class_name = $this->_ci_module_class;
array_unshift($model_paths, APPPATH . 'modules/' . $this->_ci_module_path . '/');
$module_model_name = str_replace(' ', '_', ucwords(str_replace('/', ' ', $this->_ci_module_path . ' ' . $model)));
if (isset($CI->{$module_class_name}->{$name})) {
throw new RuntimeException('The model name you are loading is the name of a resource that is already being used: ' . $module_class_name . '.' . $module_model_name);
}
} else {
if (isset($CI->{$name})) {
throw new RuntimeException('The model name you are loading is the name of a resource that is already being used: ' . $name);
}
}
if ($db_conn !== FALSE && !class_exists('CI_DB', FALSE)) {
if ($db_conn === TRUE) {
$db_conn = '';
}
$this->database($db_conn, FALSE, TRUE);
}
// Note: All of the code under this condition used to be just:
//
// load_class('Model', 'core');
//
// However, load_class() instantiates classes
// to cache them for later use and that prevents
// MY_Model from being an abstract class and is
// sub-optimal otherwise anyway.
if (!class_exists('CI_Model', FALSE)) {
$app_path = APPPATH . 'core' . DIRECTORY_SEPARATOR;
if (file_exists($app_path . 'Model.php')) {
require_once $app_path . 'Model.php';
if (!class_exists('CI_Model', FALSE)) {
throw new RuntimeException($app_path . "Model.php exists, but doesn't declare class CI_Model");
}
} elseif (!class_exists('CI_Model', FALSE)) {
require_once BASEPATH . 'core' . DIRECTORY_SEPARATOR . 'Model.php';
}
$class = config_item('subclass_prefix') . 'Model';
if (file_exists($app_path . $class . '.php')) {
require_once $app_path . $class . '.php';
if (!class_exists($class, FALSE)) {
throw new RuntimeException($app_path . $class . ".php exists, but doesn't declare class " . $class);
}
}
}
$model = ucfirst($model);
if (!class_exists($model, FALSE)) {
foreach ($model_paths as $model_path_index => $mod_path) {
if (!file_exists($mod_path . 'models/' . $path . $model . '.php')) {
continue;
}
require_once $mod_path . 'models/' . $path . $model . '.php';
if ($this->_ci_is_inside_module && $model_path_index == 0) {
if (!class_exists($module_model_name, FALSE)) {
throw new RuntimeException($mod_path . "models/" . $path . $module_model_name . ".php exists, but doesn't declare class " . $module_model_name);
}
} else {
if (!class_exists($model, FALSE)) {
throw new RuntimeException($mod_path . "models/" . $path . $model . ".php exists, but doesn't declare class " . $model);
}
}
break;
}
if ($this->_ci_is_inside_module && $model_path_index == 0) {
if (!class_exists($module_model_name, FALSE)) {
throw new RuntimeException('Unable to locate the model you have specified: ' . $module_model_name);
}
} else {
if (!class_exists($model, FALSE)) {
throw new RuntimeException('Unable to locate the model you have specified: ' . $model);
}
}
} elseif (!is_subclass_of($model, 'CI_Model')) {
throw new RuntimeException("Class " . $model . " already exists and doesn't extend CI_Model");
}
$this->_ci_models[] = $name;
if ($this->_ci_is_inside_module) {
// 一定要放到全局 loader 实例中,否则还是无法查询模型属于哪个模块
$CI->load->_ci_module_models[$module_model_name] = $module_class_name;
if ($model_path_index == 0) {
$CI->{$module_class_name}->{$name} = new $module_model_name();
} else {
$CI->{$module_class_name}->{$name} = new $model();
}
} else {
$CI->{$name} = new $model();
}
return $this;
}