Custom classes in CodeIgniter

前端 未结 6 557
走了就别回头了
走了就别回头了 2021-01-31 05:45

Seems like this is a very common problem for beginners with CodeIgniter, but none of the solutions I\'ve found so far seems very relevant to my problem. Like the topic says I\'m

相关标签:
6条回答
  • 2021-01-31 05:53

    If you have PHP version >= 5.3 you could take use of namespaces and autoloading features.

    A simple autoloader library in the library folder.

    <?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';
        }
    
    }
    ?>
    

    The User object in the model dir. ( models/User.php )

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

    And instead of new User... new models\User ( ... )

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

    And in controller just make sure to call the customautoloader like this:

    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();
    
    0 讨论(0)
  • 2021-01-31 05:57

    After a brief google search, I was inspired to make my own autoloader class. It's a bit of a hack, since I use custom Codeigniter library to preform auto-loading, but for me this is the best way, that I'm aware of, of loading all the classes, I require, without compromising my application architecture philosophy, to fit it into Codeigniter way of doing things. Some might argue that Codeigniter is not the right framework for me and that might be true, but I'm trying things out and playing around with various frameworks and while working on CI, I came up with this solution. 1. Auto-load new custom library by editing applicaion/config/autoload.php to include:

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

    and any other libraries you might need. 2. Then add library class My_loader. This class will be loaded on every request and when its constructor is run, it will recursively search through all sub-folders and require_once all .php files inside application/service & application/models/dto folders. Warning: folders should not have dot in the name, otherwise function will fail

    <?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;
        }
    }
    
    0 讨论(0)
  • 2021-01-31 06:01

    Including a class file is not a bad approach.

    In our projects, we do the same, add an another layer to MVC, and thats a Service Layer which the Controllers calls and Service calls the Model. We introduced this layer to add Business Logic seperate.

    So far, we have been using it, and our product has gone large too, and still we find no difficulty with the decision of including files that we had made in the past.

    0 讨论(0)
  • 2021-01-31 06:05

    Codeigniter has a common function to instantiate individual classes.

    It is called load_class(), found in /system/core/Common.php

    The function;

    /**
    * 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
    */
    

    The signature is

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

    An example of it being used is when you call the show_404() function.

    0 讨论(0)
  • 2021-01-31 06:07

    After 18 hours I managed to include a library in my control without initialisation (the constructor was the problem, because of that and i could't use the standard codeiginiter $this->load->library() ). Follow the https://stackoverflow.com/a/21858556/4701133 . Be aware for further native class initialization use $date = new \DateTime()with back-slash in front otherwise the function will generate an error !

    0 讨论(0)
  • 2021-01-31 06:10

    CodeIgniter doesn't really support real Objects. All the libraries, models and such, are like Singletons.

    There are 2 ways to go, without changing the CodeIgniter structure.

    1. Just include the file which contains the class, and generate it.

    2. Use the load->library or load_class() method, and just create new objects. The downside of this, is that it will always generate 1 extra object, that you just don't need. But eventually the load methods will also include the file.

    Another possibility, which will require some extra work, is to make a User_Factory library. You can then just add the object on the bottom of the file, and create new instances of it from the factory.

    I'm a big fan of the Factory pattern myself, but it's a decision you have to make yourself.

    I hope this helped you, if you have any questions that are more related to the implementation, just let me/us know.

    0 讨论(0)
提交回复
热议问题