Intereting Posts
PHP – Сделать многомерный ассоциативный массив из строки с разделителями Пользовательский валидатор в Laravel 5 Использовать параметр в функции, переданной в google.setOnLoadCallback (); PDO bindParam () с подготовленным оператором не работает Как экспортировать контакт в CSV с моей службой? Laravel orderBy дата не работает при использовании paginator Проверьте, существует ли экземпляр класса, если не создать экземпляр Какая структура PHP с Twitter Bootstrap Установите / снимите флажок (Выбрать все), если все дочерние флажки выделены в этом div Добавить разбивку на страницы в wordpress admin в моем собственном настроенном плагине Как отформатировать $ email массив для mailchimp Zend Lucene: фатальная ошибка, максимальное время выполнения простой пример кода PHP для обслуживания backbone.js php, как перейти на один уровень вверх по dirname (__ FILE__) Как подавить предупреждение в файлах PHP для Netbeans?

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

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

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

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

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

  1. Простой php включает в себя, который кажется достаточно хорошим, но поскольку я новичок в 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(); 

Если у вас есть версия 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 в каталоге модели. (модели / 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(); 

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

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

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

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

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

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

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

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

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

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

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

После краткого поиска 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; } } 

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