[英]How do you add abstract class library in the Codeigniter framework?
我在libraries
文件夾中名為AbstractClass.php
文件中有以下代碼
abstract class AbstractClass {
abstract protected doSomething ();
}
class ConcreteClass extends AbstractClass {
public function doSomething () {};
}
當我嘗試從controllers
加載AbstractClass
時,如下所示:
$this->load->library('AbstractClass');
我得到Unable to load the requested class: AbstractClass
錯誤。
我究竟做錯了什么? 我應該只包含文件而不是加載它嗎?
謝謝
很明顯,你不能直接加載一個抽象類,因為這與抽象類的觀點相悖。
您可以將一個抽象類與另一個庫一起放在一個文件中,但這有點毫無意義,並且違背了CI(以及所有良好標准)建議的“一級一檔”標准。
您可以在庫文件中包含此文件包含include(),也可以設置__autoload()函數來為您執行此操作。 __autoload()的最佳位置是config.php的底部。
我使用帶有CodeIgniter庫的抽象類,因為我有一些常用的方法,我希望所有繼承的類都可以使用,這些方法本身就沒有意義。 我不知道我建議的是最佳做法。 我懷疑它不是,但我個人覺得它很有用。 我是這樣做的:
在CodeIgniter應用程序文件夾中創建一個新的類文件夾。
將此文件夾添加到路徑中。 (我通常在控制器中這樣做。)
if (!strstr(get_include_path(), APPPATH . 'classes')) { ini_set('include_path', get_include_path() . ':' . APPPATH . 'classes'); }
在classes文件夾中創建抽象類或其他類。
創建擴展的CodeIgniter庫:
require_once('an_abstract_class.php'); class concrete_library extends an_abstract_class {
像往常一樣使用庫:
$this->load->library('concrete_library');
這應該夠了吧。 我希望這很有用。
好。 我知道這是遲到的,但我相信很多人對此都有疑問。
這實際上是核心Loader類的限制,因為它試圖實例化第一個參數定義的每個項目。 眾所周知,抽象類的定義是抽象的,不能實例化。 那么我們如何解決這個問題呢?
但最重要的是: 我們如何在符合CodeIgniter標准的同時解決這個問題?
由於我剛剛開始使用CodeIgniter,因此我無法確定過去如何處理Core Extensions。 但是,在最新版本中,CodeIgniter框架將允許您通過使用已定義的子類前綴(在大多數情況下為“MY_”)前綴文件名,然后是您計划擴展的文件的名稱來擴展和覆蓋其核心類。
* /應用/核心/ 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類的所有屬性和方法。 上面的代碼片段在技術上與原始Loader類完全相同,但最重要的是現在這個類將接管所有加載方法而不是原始方法。
現在我們需要做的就是為loader類提供了解它是否正在加載和實例化一個具體類的方法,或者它是否只包含一個抽象類。
有兩種方法可以處理任何庫的加載:
方法1) public function library
方法2) protected function _ci_load_class
如果第一個參數是數組,方法1通過迭代自身來處理傳遞給它的所有參數,確保提供的數據是干凈的,並且如果不滿足某些條件,則阻止采取任何操作。
方法2處理必要資產的實際加載,錯誤處理等。
我們可以通過在新的MY_Loader類中重新定義它們來覆蓋方法1和2的行為。 我通過創建原始方法的幾乎精確的副本來完成此操作,但添加了第4個參數 - 當為true時 - 將阻止Loader在第二個方法中實例化定義的庫類。 我還添加了一個額外的方法public function abstract_library
,它允許您以簡寫的方式將Library顯式定義為Abstract。
以下是MY_Loader.php類的完整內容。 這不會影響對庫方法的任何現有調用。
希望這可以幫助!
* /應用/核心/ 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");
?>
我沒有看到有關CI的抽象類Web的任何示例,所以我想確認您可以擁有一個抽象庫。 對於為什么抽象類有用,OOP有很好的理由是OOP的基礎。 從根本上說,我要確保兒童班遵循一定的一致性。
如果您需要一個示例,請告訴我,因為您手動必須包含抽象類,請確保只執行一次,這樣您就不會遇到重新聲明類的問題。
另外不要忘記,如果您在Abstract類中有靜態函數或變量,您仍然可以直接訪問它而無需加載類,如下所示
AbstractClass::static_method_you_want_to_call();
我找到了一種在Codeigniter中使用抽象類的簡單方法。 只需按照以下步驟操作 轉到系統文件夾中的庫
系統 - >庫 - > lib.php
abstract class B
{
public function lib1()
{
echo "This is library 1";
}
public function lib2()
{
echo "This is library 1";
}
}
class CI_lib extends B
{
public function libs(){
$this->lib1();
}
}
然后從Controller調用該lib。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.