php Невозможно повторно объявить класс/неопределенная переменная Модуль Joomla

Я еще экспериментирую с ООП, я очень новичок в этом, поэтому я создал модуль для joomla 2.5.x и внутри его основного файла php я require_once файл с таким классом:

require_once(JPATH_SITE.'/modules/'.$module_dir.'/libs/classes.php');

class.php содержит это:

class experiment
{
    function clean($input)
    {
        return filter_var($input, FILTER_SANITIZE_STRING);
    }
}

$my = new experiment;

Затем в файле php модуля я использую его так:

$name = $my->clean($params->get('name'));

До этого момента все ведет себя нормально. Но это только тогда, когда модуль появляется только один раз на той же странице. Если я дублирую модуль и использую его дважды на одной странице, я получаю ошибку Undefined variable my. Если я изменю require_once на require, я получу ошибку Cannot redeclare class experiment. Странный.

Я также пробовал if (!class_exists(.. или if(!isset($my)) { .. }, но знал, что это не сработает.

Я буду признателен за любую помощь, ура.


person durduvakis    schedule 13.07.2013    source источник


Ответы (1)


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

В результате, когда вы используете require_once(), вы видите, что во второй раз, когда вы пытаетесь включить его, ничего не происходит — что нормально, так как файл уже был включен, но переменная $my также не определена — потому что она вышел из области видимости, когда функция завершилась в первый раз.

Когда вы переключаетесь на require(), вы получаете другую ошибку, потому что вы переопределяете класс.


Решение здесь состоит в том, чтобы не устанавливать глобальные переменные при определении класса. Определите класс, а затем, когда вам нужно его использовать, создайте экземпляр этого класса. Не полагайтесь на глобальные переменные.

Если вы пытаетесь создать только один экземпляр класса (вам действительно нужно это делать?), рассмотрите возможность использования одноэлементный шаблон вместо этого.

person jcsanyi    schedule 14.07.2013
comment
Ух ты ! ха-ха, я не подумал взять $my = new experiment; из class.php и поместить его в файл модуля. Я только что сделал это благодаря вашей помощи, и это заставило меня смеяться, что это сработало отлично! спасибо, чувак, я очень ценю :) это было НАСТОЛЬКО просто. - person durduvakis; 14.07.2013
comment
Ну, я экспериментировал с этим по двум причинам. 1, чтобы я был более уверен, что имя функции не будет снова найдено во всех Joomla, и 2, конечно, чтобы медленно изучать ООП... - person durduvakis; 14.07.2013
comment
Спасибо за это, я постараюсь узнать и о шаблоне singleton! - person durduvakis; 14.07.2013
comment
@durduvakis Только не переусердствуйте с синглтоном. Им часто злоупотребляют, и часто нет реальной причины ограничивать класс только одним экземпляром. - person jcsanyi; 14.07.2013
comment
Я надеюсь, что скоро наступит день, когда мои глаза широко откроются с ООП, потому что я все еще нахожусь в точке, когда я большую часть времени не понимаю, что вижу, и напоминает мне о том, когда я впервые увидел php-код :) - person durduvakis; 14.07.2013