#php #codeigniter #classloader
#php #codeigniter #загрузчик классов
Вопрос:
По общему признанию, мой OOPHP немного шаткий, но я не вижу, что в этом плохого. В одном из моих контроллеров я включаю таблицу утилит, которая, как и контроллер, расширяет базовый CI_Controller
класс. Это приводит к фатальной ошибке:
Fatal error: Cannot redeclare class Utils in {file path}utils.php on line 88
Контроллер:
class Dashboard extends CI_Controller {
public function __construct() {
//call parent constructor
parent::__construct();
//load utils
require 'application/helpers/utils.php'; //<-- utils loaded
$this->utils = new Utils(); //<-- utils instantiated
//load Dashboard model
$this->utils->load->model('dashboard');
}
//etc...
}
utils.php:
class Utils extends CI_Controller {
//prep for forms (on join or login views)
public function prep_form() {
$this->load->helper('form');
$this->load->library('form_validation');
$this->form_validation->set_error_delimiters('<li>', '</li>');
}
//etc - more util methods
}
Почему он думает, что я ПОВТОРНО объявляю Utils
, несмотря на то, что вызываю его и создаю его экземпляр только один раз? Странно то, что у меня есть другой контроллер для другой части сайта с тем же шаблоном, и у него нет жалоб.
Наконец, я попытался переместить require
инструкцию за пределы контроллера и изменить ее на require_once
всякий случай, если что-то действительно вызывало ее дважды, и в обоих случаях страница просто зависает, в конечном итоге разрешаясь без отправки исходного кода в браузер.
Заранее спасибо.
Комментарии:
1. если вам нужен один и тот же метод в двух контроллерах, то вы должны написать метод в родительском контроллере
2. Зачем помещать служебные функции в контроллер? Почему не помощник или библиотека?
3. @Lefters — я не был ясен; мои утилиты находятся в помощнике. Просто они принимают форму методов, то есть ссылаются
$this
, поэтому они не являются процедурными. Возможно, это делает помощников неподходящим для них местом.4. они говорят
Unlike most other systems in CodeIgniter, Helpers are not written in an Object Oriented format. They are simple, procedural functions. Each helper function performs one specific task, with no dependence on other functions.
Ответ №1:
Переименовать
helpers/utils.php
Для
helpers/Utils.php .
Серверы, отличные от Windows, обрабатывают имя класса, должно совпадать с именем файла.
Надеюсь, это вам поможет.
Ответ №2:
Используйте $this->load->helper () вместо require()
Ответ №3:
почему бы вам просто не позвонить:
$this->load->library('utils'); // needs to be stored in the libraries directory
вместо
require 'application/helpers/utils.php'; //<-- utils loaded
$this->utils = new Utils(); //<-- utils instantiated
Комментарии:
1. Потому что utils (несмотря на его, возможно, неподходящее имя) имеет методы, т. Е. Которые используют
$this
, а не только процедурные функции. Возможно, я поступил неправильно.2. @Utkanos вы можете использовать get_instance(), чтобы получить ссылку на объект CI для использования вместо $this в помощнике. Обычно я использую $CI =amp; get_instance(), а затем использую $CI, как если бы это было $this
3. Ах, интересный ответ:
get_instance()
. Как бы ваши помощники получили к нему доступ — передав его им в качестве аргумента?4. @Utkanos вы бы вызывали это внутри каждой вспомогательной функции, которая в этом нуждается, нет необходимости передавать ее как аргумент. Также вы можете добавить вспомогательный файл в autoload.php таким образом, вы можете вызывать эти функции напрямую из любого места, не загружая ничего или не добавляя к нему префикс $this-> или что-либо еще
Ответ №4:
Я понятия не имею, почему вы пытаетесь передать класс, расширенный от CI_Controller, вашему помощнику. Помощники для вспомогательных функций (например, сортировать результат MySQL по ключу и т. Д.). Может быть, вам нужно model
?
Если вам нужна функция CodeIgniter в вашем помощнике, просто используйте get_instance()
вместо этого $this
function prep_form() {
get_instance()->load->helper('form');
get_instance()->load->library('form_validation');
get_instance()->form_validation->set_error_delimiters('<li>', '</li>');
}
Комментарии:
1. Причина в следующем: мои помощники содержат методы, а не процедурные функции. То есть они ссылаются
$this
. Другими словами, они содержат методы, которые должны быть общими, то есть доступными для всех контроллеров. Если есть лучший способ (и может быть), я весь внимание!2. @Utkanos Итак, вам следует расширить свой базовый контроллер ( ellislab.com/codeigniter/user-guide/general/core_classes.html ) и расширяйте свои контроллеры от него
3. Хорошо, это за пределами моих знаний. Я прочитаю ссылку, которую вы дали. Вы хотите сказать, что вместо прямого расширения моих контроллеров
CI_Controller
я ввожу пользовательский базовый класс, который находится между этими двумя этапами?4. @Utkanos Да. Поместите
MY_Controller.php
вapp/core/
, который будет похожclass MY_Controller extends CI_Controller { function __construct() { parent::__construct();} function test(){echo "I'm here";}}
, и на вашем контроллере используйте его:class Dashboard extends MY_Controller {function index(){$this->test();}}
5. Спасибо, я изучу это.
Ответ №5:
попробуйте
require_once 'application/helpers/utils.php';
чтобы избежать этой ошибки.
Ответ №6:
require 'application/helpers/utils.php'; //<-- utils loaded
Этот, вероятно, вызывается дважды. Вы либо создаете Dashboard
экземпляр дважды, либо еще раз включаете этот файл в другое место.
Комментарии:
1. Это то, что я думал, но от этого не осталось и следа. На самом деле, несмотря на то, что парень удалил свой ответ, изменение имени модели с ‘modelname’ на ‘modelname_model’ по какой-то причине исправило это. Запутался. В любом случае спасибо.