Хорошо.Я знаю, что уже поздно, но я уверен, что у многих людей возникают вопросы по этому поводу.
Это на самом деле ограничение основного класса Loader, поскольку он пытается создать экземпляр каждого из элементов, определенных первымпараметр.Как мы все знаем, абстрактные классы по определению являются абстрактными и не могут быть созданы.Итак, как нам обойти это?
Но самое главное: Как мы можем обойти это в соответствии со стандартами CodeIgniter?
Поскольку я только началиспользуя CodeIgniter, я не могу точно сказать, как обрабатывались Core Extensions в прошлом.Однако в самой последней версии платформа CodeIgniter позволит вам расширять и переопределять его базовые классы, добавляя префикс имени файла к определенному префиксу подкласса (в большинстве случаев «MY_»), за которым следует имя файла, который вы планируете расширять.
* / application / core / MY_Loader.php *
<?php
if(!defined('BASEPATH')) exit('No direct script access allowed');
class MY_Loader extends CI_Loader{
public function __construct(){
parent::__construct();
}
}
?>
Скорее всего, если вы знаете, как использовать абстрактные классы, вы знаете, что это делает.По сути, этот класс теперь наследует все свойства и методы исходного класса CI_Loader.Приведенный выше фрагмент кода технически является точной копией исходного класса загрузчика, но самое важное здесь заключается в том, что теперь этот класс будет принимать все методы загрузки, а не исходный.
Теперь все, что нам нужно сделать, этопредоставить классу загрузчика средства, позволяющие узнать, загружается ли он и создается ли конкретный класс, или просто включает в себя абстрактный класс.
Существует два метода, которые обрабатывают загрузку любых библиотек:
Метод 1) public function library
Метод 2) protected function _ci_load_class
Метод 1 обрабатывает все передаваемые ему параметры путем итерации через себя, если первый параметр является массивом, проверяет, предоставлены ли данныеявляется чистым и предотвращает выполнение каких-либо действий, если определенные критерии не выполнены.
Метод 2 обрабатывает фактическую загрузку необходимых ресурсов, обработку ошибок и т. д.
Мы можем переопределитьповедение методов 1 и 2 путем переопределения их в нашем новом классе MY_Loader.Я сделал это путем создания почти точных копий исходных методов, но с добавлением 4-го параметра, который - при значении true - не позволит загрузчику создавать экземпляр определенного класса библиотеки во втором методе.Я также включил дополнительный метод public function abstract_library
, который позволит вам явным образом кратко определить библиотеку как абстрактную.
Ниже приведен класс MY_Loader.php во всей его полноте.Это не повлияет на любые существующие вызовы метода библиотеки.
Надеюсь, это поможет!
* / application / core / MY_Loader.php *
<?php
if(!defined('BASEPATH')) exit('No direct script access allowed');
class MY_Loader extends CI_Loader{
public function __construct(){
parent::__construct();
}
public function library($library = '', $params = NULL, $object_name = NULL, $is_abstract=false){
if(is_array($library)){
foreach ($library as $class){
$this->library($class, $params);
}
return;
}
if($library == '' OR isset($this->_base_classes[$library])){
return FALSE;
}
if(!is_null($params) && ! is_array($params)){
$params = NULL;
}
$this->_ci_load_class($library, $params, $object_name, $is_abstract);
}
public function abstract_library($library=''){
$this->library($library, NULL , NULL, true);
}
protected function _ci_load_class($class, $params = NULL, $object_name = NULL, $is_abstract=false)
{
$class = str_replace('.php', '', trim($class, '/'));
$subdir = '';
if(($last_slash = strrpos($class, '/')) !== FALSE){
$subdir = substr($class, 0, $last_slash + 1);
$class = substr($class, $last_slash + 1);
}
foreach(array(ucfirst($class), strtolower($class)) as $class){
$subclass = APPPATH.'libraries/'.$subdir.config_item('subclass_prefix').$class.'.php';
if(file_exists($subclass)){
$baseclass = BASEPATH.'libraries/'.ucfirst($class).'.php';
if (!file_exists($baseclass)){
log_message('error', "Unable to load the requested class: ".$class);
show_error("Unable to load the requested class: ".$class);
}
if(in_array($subclass, $this->_ci_loaded_files)){
if(!is_null($object_name)){
$CI =& get_instance();
if(!isset($CI->$object_name)){
return $is_abstract ? true : $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);
}
}
$is_duplicate = TRUE;
log_message('debug', $class." class already loaded. Second attempt ignored.");
return;
}
include_once($baseclass);
include_once($subclass);
$this->_ci_loaded_files[] = $subclass;
return $is_abstract ? true : $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);
}
$is_duplicate = FALSE;
foreach ($this->_ci_library_paths as $path){
$filepath = $path.'libraries/'.$subdir.$class.'.php';
if(!file_exists($filepath)){
continue;
}
if(in_array($filepath, $this->_ci_loaded_files)){
if(!is_null($object_name)){
$CI =& get_instance();
if(!isset($CI->$object_name)){
return $is_abstract ? true : $this->_ci_init_class($class, '', $params, $object_name);
}
}
$is_duplicate = TRUE;
log_message('debug', $class." class already loaded. Second attempt ignored.");
return;
}
include_once($filepath);
$this->_ci_loaded_files[] = $filepath;
return $is_abstract ? true : $this->_ci_init_class($class, '', $params, $object_name);
}
} // END FOREACH
if($subdir == ''){
$path = strtolower($class).'/'.$class;
return $this->_ci_load_class($path, $params, $is_abstract);
}
if($is_duplicate == FALSE){
log_message('error', "Unable to load the requested class: ".$class);
show_error("Unable to load the requested class: ".$class);
}
}
}
?>
Загрузка абстрактной библиотеки:
<?php
$this->load->library("My_Abstract_Library", NULL, NULL, true);
/* -- OR -- */
$this->load->abstract_library("My_Abstract_Library");
?>