Пользовательские классы в CodeIgniter - PullRequest
18 голосов
/ 01 марта 2012

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

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

Я пытался использовать функции load (library-> load ('myclass')) в CodeIgniter, который работает, за исключением того, что сначала он пытается создать объект класса вне модели. Это, очевидно, проблема, поскольку Конструктор ожидает несколько параметров.

Решения, которые я нашел до сих пор:

  1. Простой php include, который кажется достаточно хорошим, но так как я новичок в CodeIgniter Я хочу убедиться, что я придерживаюсь его так же, как возможно.
  2. Создание «класса-оболочки», как было предложено здесь , однако я не уверен, как бы это реализовать.

класс, который я хочу включить, 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 ]

17 голосов
/ 02 марта 2012

Если у вас версия PHP> = 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 в модели dir.(models / User.php)

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

И вместо нового пользователя ... новые модели \ 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();
6 голосов
/ 01 марта 2012

CodeIgniter на самом деле не поддерживает реальные объекты.Все библиотеки, модели и тому подобное похожи на Singletons.

Есть 2 способа, без изменения структуры CodeIgniter.

  1. Просто включите файл, который содержиткласса и сгенерируйте его.

  2. Используйте метод load-> library или load_class () и просто создайте новые объекты.Недостатком этого является то, что он всегда будет генерировать 1 дополнительный объект, который вам просто не нужен.Но в конечном итоге методы загрузки также будут включать файл.

Другая возможность, которая потребует дополнительной работы, - создать библиотеку User_Factory.Затем вы можете просто добавить объект в конец файла и создать его новые экземпляры с завода.

Я сам большой поклонник шаблона Factory, но это решение, которое вы должны принятьВы сами.

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

3 голосов
/ 01 марта 2012

Включение файла класса - неплохой подход.

В наших проектах мы делаем то же самое, добавляем еще один слой в MVC, и это сервисный уровень, который вызывают контроллеры, а сервис вызывает модель. Мы ввели этот слой, чтобы добавить Business Logic отдельно.

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

1 голос
/ 01 марта 2012

Codeigniter имеет общую функцию для создания отдельных классов.

Он называется load_class () , находится в / system / core / Common.php

Функция;

/**
* 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 () .

0 голосов
/ 15 октября 2015

Через 18 часов мне удалось включить библиотеку в свой элемент управления без инициализации (из-за этого возникла проблема с конструктором, и я не смог использовать стандартный кодовый указатель $this->load->library()). Следуйте https://stackoverflow.com/a/21858556/4701133. Помните, что для дальнейшей инициализации собственного класса используйте $date = new \DateTime() с обратной косой чертой впереди, в противном случае функция выдаст ошибку!

0 голосов
/ 08 марта 2014

После короткого поиска в Google я был вдохновлен на создание собственного класса автозагрузчика.Это что-то вроде хака, так как я использую собственную библиотеку Codeigniter для предварительной загрузки автоформата, но для меня это лучший из известных мне способов загрузки всех нужных мне классов без ущерба для философии архитектуры приложения., чтобы вписать его в Codeigniter способ делать вещи.Кто-то может возразить, что Codeigniter не является подходящей для меня платформой, и это может быть правдой, но я пробую разные вещи и играю с различными фреймворками, и, работая над CI, я придумал это решение.1. Автоматически загрузите новую пользовательскую библиотеку, отредактировав файл applicationaion / config / autoload.php, включив в него:

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

и любые другие библиотеки, которые могут вам понадобиться.2. Затем добавьте библиотеку класса My_loader.Этот класс будет загружаться при каждом запросе, и при запуске его конструктора он будет рекурсивно искать все подпапки и требовать_ всех файлов .php внутри папок application / service & 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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...