CodeIgniter中的自定义类

时间:2012-03-01 06:30:01

标签: php codeigniter

对于使用CodeIgniter的初学者来说,这似乎是一个非常常见的问题,但到目前为止我找到的解决方案似乎与我的问题无关。就像主题所说我试图在CodeIgniter中包含一个自定义类。

我正在尝试创建下面类的几个对象并将它们放在一个数组中,因此我需要该类可用于模型。

我尝试在CodeIgniter中使用load(library-> load('myclass')函数,除了它首先尝试在模型外部创建类的对象之外,这种函数显然是个问题。构造函数需要几个参数。

到目前为止我找到的解决方案是

  1. 一个简单的php包括看起来很好,但是因为我是新手 CodeIgniter我想确保我坚持不懈 可能的。
  2. 按照建议的here创建一个“包装类”,但是我不确定如何实现它。
  3. 我要包括的课程, 的 user.php的

    <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); 
    class User{
        public $ID = 0;
        public $username = 0;
        public $access_lvl = 0;
        public $staff_type = 0;
        public $name = 0;    
    
        public function __construct($ID, $username, $access_lvl, $staff_type, $name) 
        {
            $this->ID = $ID;
            $this->username = $username;
            $this->access_lvl = $access_lvl;
            $this->staff_type = $staff_type;
            $this->name = $name;
        }
    
        public function __toString() 
        {
            return $this->username;
        }
    }
    ?>
    

    需要User.php的方法(模型)

    function get_all_users()
    {
        $query = $this->db->get('tt_login');
        $arr = array();
    
        foreach ($query->result_array() as $row)
        {
            $arr[] = new User
            (
                $row['login_ID'],
                $row['login_user'],
                $row['login_super'],
                $row['crew_type'],
                $row['login_name']
            );
        }    
    
        return $arr;
    }
    

    最后是控制器,

    function index()
    {
            $this->load->library('user');
            $this->load->model('admin/usersmodel', '', true);            
    
            // Page title
            $data['title'] = "Some title";
            // Heading
            $data['heading'] = "Some heading";
            // Data (users)
            $data['users'] = $this->usersmodel->get_all_users();
    

6 个答案:

答案 0 :(得分:17)

如果你有PHP版本&gt; = 5.3,你可以使用名称空间自动加载功能。

库文件夹中的简单自动加载器库。

<?php
class CustomAutoloader{

    public function __construct(){
        spl_autoload_register(array($this, 'loader'));
    }

    public function loader($className){
        if (substr($className, 0, 6) == 'models')
            require  APPPATH .  str_replace('\\', DIRECTORY_SEPARATOR, $className) . '.php';
    }

}
?>

模型目录中的User对象。 (models / User.php)

<?php 
namespace models; // set namespace
if ( ! defined('BASEPATH')) exit('No direct script access allowed'); 
class User{
 ...
}

而不是新用户... 新模型\用户(...)

function get_all_users(){
    ....
    $arr[] = new models\User(
    $row['login_ID'],
    $row['login_user'],
    $row['login_super'],
    $row['crew_type'],
    $row['login_name']
    );
    ...
}

在控制器中,请务必按照以下方式调用customautoloader:

function index()
{
        $this->load->library('customautoloader');
        $this->load->model('admin/usersmodel', '', true);            

        // Page title
        $data['title'] = "Some title";
        // Heading
        $data['heading'] = "Some heading";
        // Data (users)
        $data['users'] = $this->usersmodel->get_all_users();

答案 1 :(得分:6)

CodeIgniter并不真正支持真正的对象。 所有的图书馆,模型等都像单身人士。

有两种方法可以使用,而无需更改CodeIgniter结构。

  1. 只需包含包含该类的文件,然后生成它。

  2. 使用load-&gt; library或load_class()方法,只需创建新对象。这样做的缺点是,它总会产生一个额外的对象,你不需要它。但最终加载方法也将包含该文件。

  3. 另一种可能需要额外工作的可能性是制作User_Factory库。 然后,您可以在文件底部添加对象,并从工厂创建它的新实例。

    我自己是工厂模式的忠实粉丝,但这是你必须做出的决定。

    我希望这对您有所帮助,如果您有任何与实施相关的问题,请告诉我/我们。

答案 2 :(得分:3)

包含类文件并不是一个糟糕的方法。

在我们的项目中,我们也这样做,向MVC添加另一层,这就是控制器调用和服务调用模型的服务层。我们引入了这一层来添加Business Logic分离。

到目前为止,我们一直在使用它,而且我们的产品也变得很大,我们仍然认为包含我们过去制作的文件的决定没有任何困难。

答案 3 :(得分:1)

Codeigniter具有实例化单个类的通用功能。

/system/core/Common.php中找到 load_class()

功能;

/**
* Class registry
*
* This function acts as a singleton.  If the requested class does not
* exist it is instantiated and set to a static variable.  If it has
* previously been instantiated the variable is returned.
*
* @access   public
* @param    string  the class name being requested
* @param    string  the directory where the class should be found
* @param    string  the class name prefix
* @return   object
*/

签名是

load_class($class, $directory = 'libraries', $prefix = 'CI_')

使用它的一个示例是当您调用 show_404()函数时。

答案 4 :(得分:0)

经过短暂的谷歌搜索后,我受到鼓舞,开始自己制作自动加载器课程。这是一个黑客,因为我使用自定义Codeigniter库来预先自动加载,但对我而言,这是我所知道的加载所有类的最佳方式,我需要,而不会影响我的应用程序架构理念,使其适合Codeigniter的做事方式。有些人可能认为Codeigniter对我来说不是正确的框架,这可能是真的,但我正在尝试各种框架,并在研究CI时,我想出了这个解决方案。 1.通过编辑applicaion / config / autoload.php自动加载新的自定义库以包含:

$autoload['libraries'] = array('my_loader');

以及您可能需要的任何其他库。 2.然后添加库类My_loader。这个类将在每个请求上加载,当它的构造函数运行时,它将递归搜索application / service&amp;中的所有子文件夹和require_once所有.php文件。 application / models / dto文件夹。警告:文件夹名称中不应包含点,否则功能将失败

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

class My_loader {

    protected static $_packages = array(
            'service',
            'models/dto'
            );

    /**
     * Constructor loads service & dto classes
     * 
     * @return void
     */
    public function __construct($packages = array('service', 'models/dto'))
    {
        // files to be required
        $toBeRequired = array();

        // itrate through packages
        foreach ($packages as $package) {
            $path = realpath(APPPATH . '/' . $package . '/');
            $toBeRequired = array_merge($toBeRequired, $this->findAllPhpFiles($path));
        }

        /**
         * Require all files
         */
        foreach ($toBeRequired as $class) {
            require_once $class;
        }
    }

    /**
     * Find all files in the folder
     * 
     * @param string $package
     * @return string[]
     */
    public function findAllPhpFiles($path)
    {
        $filesArray = array();
        // find everithing in the folder
        $all = scandir($path);
        // get all the folders
        $folders = array_filter($all, get_called_class() . '::_folderFilter');
        // get all the files
        $files = array_filter($all, get_called_class() . '::_limitationFilter');

        // assemble paths to the files
        foreach ($files as $file) {
            $filesArray[] = $path . '/' . $file;
        }
        // recursively go through all the sub-folders
        foreach ($folders as $folder) {
            $filesArray = array_merge($filesArray, $this->findAllPhpFiles($path . '/' . $folder));
        }

        return $filesArray;
    }

    /**
     * Callback function used to filter out array members containing unwanted text
     * 
     * @param string $string
     * @return boolean
     */
    protected static function _folderFilter($member) {
        $unwantedString = '.';
        return strpos($member, $unwantedString) === false;
    }

    /**
     * Callback function used to filter out array members not containing wanted text
     *
     * @param string $string
     * @return boolean
     */
    protected static function _limitationFilter($member) {
        $wantedString = '.php';
        return strpos($member, $wantedString) !== false;
    }
}

答案 5 :(得分:0)

18小时后,我设法在我的控件中包含一个库而没有初始化(构造函数是问题所在,因此我不能使用标准的codeiginiter $this->load->library())。 关注https://stackoverflow.com/a/21858556/4701133。请注意进一步的本机类初始化使用前面带有反斜杠的$date = new \DateTime()否则该函数将生成错误!