2012-06-25 4 views
4

Возможно ли реализовать абстрактную базовую модель в Codeigniter? Я создал абстрактный класс, который имеет базовые функции CRUD, но я получаю ошибку «Не могу создать экземпляр абстрактного класса».Codeigniter абстрактная базовая модель

Абстрактная модель находится в /application/core/my_model.php и просто

abstract class MY_Model extends CI_Model 
{ 

Невозможно создать абстрактный класс»на линии 174 /system/core/Common.php

Похоже, что Codeigniter пытается создать экземпляр my_model.php, когда он загружается, что я предполагаю, связано с тем, что файлы в папке/core используются как место для расширения основных системных файлов, таких как Controller и Model. Есть ли способ остановить это? Я пытался автозагрузить модель, используя Phil Sturgeon's native autoload, но это не помогло.

/* 
| ------------------------------------------------------------------- 
| Native Auto-load 
| ------------------------------------------------------------------- 
| 
| Nothing to do with cnfig/autoload.php, this allows PHP autoload to work 
| for base controllers and some third-party libraries. 
| 
*/ 

function __autoload($class) 
{ 
    if(strpos($class, 'CI_') !== 0) 
    { 
     @include_once(APPPATH . 'core/'. $class . EXT); 
    } 
} 

Я понимаю, что простой способ сделать это будет состоять только в том, чтобы включить файл в начало каждой модели, в которой я хотел использовать его, но, очевидно, это было бы менее оптимальным.

ответ

3

Зачем делать MY_Model abstract? Вы можете использовать все свои функции CRUD в MY_Model и расширить свои модели от MY_Model вместо CI_Model. Не нужно использовать автозагрузку, так как CodeIgniter позволяет вам расширять CI_Model с помощью MY_Model, пока вы кладете основную папку.

Хороший пример MY_Model - это пример от Джейми Румбелова. Вы найдете его здесь: https://github.com/jamierumbelow/codeigniter-base-model/

Удачи вам!

Приветствия

Барт

2

Я пытаюсь настроить класс Loader в принятии тезисов и интерфейсов.

Сначала я помещаю все мои правки в мою /application/core/MY_Loader.php:

<?php if (! defined('BASEPATH')) exit('No direct script access allowed'); 
/** 
* CodeIgniter 
* 
* An open source application development framework for PHP 5.1.6 or newer 
* 
* @package  CodeIgniter 
* @author  ExpressionEngine Dev Team 
* @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. 
* @license  http://codeigniter.com/user_guide/license.html 
* @link  http://codeigniter.com 
* @since  Version 1.0 
* @filesource 
*/ 

// ------------------------------------------------------------------------ 
// Joseff Betancourt - 11/14/2012 modified code by adding a autoloader and interface loader copied from model loader. 

/** 
* Loader Class 
* 
* Loads views and files 
* 
* @package  CodeIgniter 
* @subpackage Libraries 
* @author  ExpressionEngine Dev Team 
* @category Loader 
* @link  http://codeigniter.com/user_guide/libraries/loader.html 
*/ 
class MY_Loader extends CI_Loader { 

    // All these are set automatically. Don't mess with them. 
    /** 
    * Nesting level of the output buffering mechanism 
    * 
    * @var int 
    * @access protected 
    */ 

    protected $_ci_abstracts_paths  = array(); 
    /** 
    * List of paths to load models from 
    * 
    * @var array 
    * @access protected 
    */ 
    protected $_ci_interfaces_paths  = array(); 
    /** 
    * List of paths to load helpers from 
    * 
    * @var array 
    * @access protected 
    */ 

    protected $_ci_abstracts   = array(); 
    /** 
    * List of loaded interfaces 
    * 
    * @var array 
    * @access protected 
    */ 
    protected $_ci_interfaces   = array(); 
    /** 
    * List of loaded helpers 
    * 
    * @var array 
    * @access protected 
    */ 

    /** 
    * Constructor 
    * 
    * Sets the path to the view files and gets the initial output buffering level 
    */ 

    function __construct() 
    { 
     parent::__construct(); 
     $this->_ci_abstracts_paths = array(APPPATH); 
     $this->_ci_interfaces_paths = array(APPPATH); 
     log_message('debug', "Loader Class Initialized"); 
    } 

    // -------------------------------------------------------------------- 

    /** 
    * Initialize the Loader 
    * 
    * This method is called once in CI_Controller. 
    * 
    * @param array 
    * @return object 
    */ 
    public function initialize() 
    { 

     $this->_ci_abstracts = array(); 
     $this->_ci_interfaces = array(); 
     $this->_ci_autoloader(); 

     return $this; 
    } 

    // -------------------------------------------------------------------- 

    /** 
    * Abstracts Loader 
    * 
    * This function lets users load and instantiate models. 
    * 
    * 11/14/2012 - Joseff Betancourt - Cloned from Models 
    * 
    * @param string the name of the class 
    * @param string name for the abstract 
    * @param bool database connection 
    * @return void 
    */ 
    public function abstracts($abstracts, $name = '', $db_conn = FALSE) 
    { 
     if (is_array($abstracts)) 
     { 
      foreach ($abstracts as $babe) 
      { 
       $this->abstracts($babe); 
      } 
      return; 
     } 

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

     $path = ''; 

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

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

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

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

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

     $abstracts = strtolower($abstracts); 

     foreach ($this->_ci_abstracts_paths as $mod_path) 
     { 
      if (! file_exists($mod_path.'abstracts/'.$path.$abstracts.'.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_Abstracts')) 
      { 
       load_class('Abstracts', 'core'); 
      } 

      require_once($mod_path.'abstracts/'.$path.$abstracts.'.php'); 

      $abstracts = ucfirst($abstracts); 

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

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

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

    // -------------------------------------------------------------------- 

    /** 
    * Interface Loader 
    * 
    * This function lets users load and instantiate interfaces. 
    * 
    * 11/14/2012 - Joseff Betancourt - Cloned from Models 
    * 
    * @param string the name of the class 
    * @param string name for the interface 
    * @param bool database connection 
    * @return void 
    */ 
    public function interfaces($interfaces, $name = '', $db_conn = FALSE) 
    { 
     if (is_array($interfaces)) 
     { 
      foreach ($interfaces as $babe) 
      { 
       $this->interfaces($babe); 
      } 
      return; 
     } 

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

     $path = ''; 

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

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

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

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

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

     $interfaces = strtolower($interfaces); 

     foreach ($this->_ci_interfaces_paths as $mod_path) 
     { 
      if (! file_exists($mod_path.'interfaces/'.$path.$interfaces.'.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_Interfaces')) 
      { 
       load_class('Interfaces', 'core'); 
      } 

      require_once($mod_path.'interfaces/'.$path.$interfaces.'.php'); 

      $interfaces = ucfirst($interfaces); 

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

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

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

    // -------------------------------------------------------------------- 


    /** 
    * Autoloader 
    * 
    * The config/autoload.php file contains an array that permits sub-systems, 
    * libraries, and helpers to be loaded automatically. 
    * 
    * @param array 
    * @return void 
    */ 
    private function _ci_autoloader() 
    { 
     // Abstracts models 
     if (isset($autoload['abstracts'])) 
     { 
      $this->model($autoload['abstracts']); 
     } 

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

    } 

    // -------------------------------------------------------------------- 

} 

/* End of file Loader.php */ 
/* Location: ./system/core/Loader.php */ 

Тогда я копируя ядро ​​Model.php в Abstracts.php и Interfaces.php (заменить word Model с помощью or) и поместить их в папку application/core /.

В автозагрузке я добавил

/* 
| ------------------------------------------------------------------- 
| Auto-load Interfaces 
| ------------------------------------------------------------------- 
| Prototype: 
| 
| $autoload['interfaces'] = array('interface1', 'interface2'); 
| 
*/ 

$autoload['interfaces'] = array(); 


/* 
| ------------------------------------------------------------------- 
| Auto-load Abstracts 
| ------------------------------------------------------------------- 
| Prototype: 
| 
| $autoload['abstracts'] = array('abstract1', 'abstract2'); 
| 
*/ 

$autoload['abstracts'] = array(); 

и, наконец, я добавил папку в папке приложения для рефератов и интерфейсов. Не полностью доказано, но я думаю, что это немного более целостный подход, позволяющий человеку загружать тезисы, когда это необходимо для ссылки.

Также вы бы создать аннотацию внутри абстрактной папки, как это:

abstract class MY_Model extends CI_Model 
{ 

blah 

} 
+0

https://github.com/Joseffb/CIAI.git - это код, который я собрал вместе.Надеюсь, это может помочь, и люди могут внести свой вклад во все, что я испортил. – Joseff

+0

Просто уточнить ... Вам действительно нужно взломать (или расширить) CORE, чтобы заставить это работать на CI? FML, почему бы просто не использовать FuelPHP ... ?? или что-то, что фактически поддерживает обычные методы ООП? Зачем это делать? – rckehoe

0

Сохранить файл в /application/core/MY_model.php:

<?php if (! defined('BASEPATH')) exit('No direct script access allowed'); 

class MY_model extends CI_Model 
{ 
    public function __construct() 
    { 
     parent::__construct(); 
    } 

    // Return all records in the table 
    public function get_all($table) 
    { 
     $q = $this->db->get($table); 
     if($q->num_rows() > 0) 
     { 
      return $q->result(); 
     } 
     return array(); 
    } 

    // Return only one row 
    public function get_row($table,$primaryfield,$id) 
    { 
     $this->db->where($primaryfield,$id); 
     $q = $this->db->get($table); 
     if($q->num_rows() > 0) 
     { 
      return $q->row(); 
     } 
     return false; 
    } 

    // Return one only field value 
    public function get_data($table,$primaryfield,$fieldname,$id) 
    { 
     $this->db->select($fieldname); 
     $this->db->where($primaryfield,$id); 
     $q = $this->db->get($table); 
     if($q->num_rows() > 0) 
     { 
      return $q->result(); 
     } 
     return array(); 
    } 

    // Insert into table 
    public function add($table,$data) 
    { 
     return $this->db->insert($table, $data); 
    } 

    // Update data to table 
    public function update($table,$data,$primaryfield,$id) 
    { 
     $this->db->where($primaryfield, $id); 
     $q = $this->db->update($table, $data); 
     return $q; 
    } 

    // Delete record from table 
    public function delete($table,$primaryfield,$id) 
    { 
     $this->db->where($primaryfield,$id); 
     $this->db->delete($table); 
    } 

    // Check whether a value has duplicates in the database 
    public function has_duplicate($value, $tabletocheck, $fieldtocheck) 
    { 
     $this->db->select($fieldtocheck); 
     $this->db->where($fieldtocheck,$value); 
     $result = $this->db->get($tabletocheck); 

     if($result->num_rows() > 0) { 
      return true; 
     } 
     else { 
      return false; 
     } 
    } 

    // Check whether the field has any reference from other table 
    // Normally to check before delete a value that is a foreign key in another table 
    public function has_child($value, $tabletocheck, $fieldtocheck) 
    { 
     $this->db->select($fieldtocheck); 
     $this->db->where($fieldtocheck,$value); 
     $result = $this->db->get($tabletocheck); 

     if($result->num_rows() > 0) { 
      return true; 
     } 
     else { 
      return false; 
     } 
    } 

    // Return an array to use as reference or dropdown selection 
    public function get_ref($table,$key,$value,$dropdown=false) 
    { 
     $this->db->from($table); 
     $this->db->order_by($value); 
     $result = $this->db->get(); 

     $array = array(); 
     if ($dropdown) 
      $array = array("" => "Please Select"); 

     if($result->num_rows() > 0) { 
      foreach($result->result_array() as $row) { 
      $array[$row[$key]] = $row[$value]; 
      } 
     } 
     return $array; 
    } 
} 

затем распространяются как так

class any_model extends MY_Model 
{ 
    public function __construct() 
    { 
     parent::__construct(); 
    } 
} 
Смежные вопросы