Пользовательские классы в CodeIgniter - программирование
Подтвердить что ты не робот

Пользовательские классы в CodeIgniter

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

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

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

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

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

Класс, который я хочу включить, 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();
4b9b3361

Ответ 1

Если у вас есть версия PHP >= 5.3, вы можете использовать функции namespaces и для автозагрузки.

Простая библиотека автозагрузчика в папке библиотеки.

<?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 в каталоге модели. (модели/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();

Ответ 2

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

Есть два способа пойти, не меняя структуру CodeIgniter.

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

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

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

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

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

Ответ 3

Включение файла класса не является плохим подходом.

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

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

Ответ 4

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

Ответ 5

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

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

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

Ответ 6

Через 18 часов мне удалось включить библиотеку в мой элемент управления без инициализации (конструктор был проблемой, из-за этого и я не мог использовать стандартный codeiginiter $this->load->library()). Следуйте fooobar.com/info/324268/.... Имейте в виду, что для дальнейшей инициализации исходного класса используйте $date = new \DateTime() с обратной косой чертой, иначе функция будет генерировать ошибку!