require_once () в классе - PullRequest
       5

require_once () в классе

5 голосов
/ 15 мая 2011

Я заметил, что если я объявляю функцию внутри метода класса, имя которого совпадает с именем внешней функции, я получаю сообщение об ошибке:

function a(){
  ...
}

class foo{
  public function init(){
    function a(){  // <- error
    ...    
    }
    ...
  }

}

, однако это будет работать:

function a(){
  ...
}

class foo{
  public static function a(){
    ...
  }
}

Могу ли я включить набор функций, которые действуют как статические методы для этого класса, используя require_once или что-то подобное?

require_once('file.php'); после class foo{ не работает ...

Ответы [ 4 ]

3 голосов
/ 15 мая 2011

PHP позволяет вкладывать объявления функций в другие, но на самом деле не имеет вложенных функций. Они всегда оказываются в глобальном масштабе. Таким образом, a(), который вы определили в своем методе init, конфликтует с уже определенным function a().

static function a() связано с пространством имен класса, даже если оно ведет себя как функция, а не метод.

Вызов оператора require_once в определении класса невозможен. Синтаксис PHP не позволяет этого. Определения классов - это специальные области видимости / языковые конструкции, которые допускают только объявления функций или переменных на уровне непосредственного анализа. - Таким образом, PHP не позволяет этого (классы и их методы должны быть объявлены сразу, а не собраны), и нет действительно хороших или рекомендуемых обходных путей для того, что вы хотите.

1 голос
/ 15 мая 2011

Если позволяет структура вашего класса, вы можете разделить класс на несколько разных классов, которые являются частью цепочки наследования:

class foo1 {
    public static function a() {}
}
class foo extends foo1 {
    public static function b() {}
}

В качестве альтернативы, вы можете использовать __ callStatic () , если вы хотите снизить производительность. (Требуется PHP 5.3; хотя, если вам нужны только нестатические методы, __call доступен с 5.0.) Smarty 3 делает это IIRC.

class foo {
    private static $parts = array('A', 'B');
    public static __callStatic($name, $arguments) {
        foreach (self::$parts as $part) {
            if (method_exists($part, $name)) {
                return call_user_func_array(array($part, $name), $arguments);
            }
        }
        throw new Exception();
    }
}
class A {
    public static function a() {}
}
class B {
    public static function b() {}
}

PHP 5.4 будет предположительно включать черты, которые являются более простым способом включения внешнего кода в класс:

class foo {
    use A, B;
}
trait A {
    public static function a() {}
}
trait B {
    public static function b() {}
}
1 голос
/ 15 мая 2011

Предполагая, что определение второго метода "a" недопустимо, вам нужно переместить его за пределы метода init.

Похоже, ваш вызов require_once является проблемой (определенно не должен вызываться внутри класса). Не могли бы вы опубликовать полный пример, включая ваш звонок require_once, который не работает?

1 голос
/ 15 мая 2011

Чтобы ответить на вопрос: сначала вы должны проверить, была ли уже реализована функция a, используя function_exists:

class foo{
  public function init(){
    if(!function_exists('a')):
    function a(){  // <- will only be declared when it doesn't already exist
        ...    
    }
    endif;
    ...
  }

}

Однако, это очень плохопрактика кодирования .Очень скоро все будет в порядке, поскольку вы не будете знать, что именно происходит и какая функция будет использоваться.Я бы сказал, что вам лучше использовать подкласс и require_once соответствующий подкласс.

...