Назовите защищенный метод снаружи класса в PHP

Вот моя версия:

//initialize array a with values from 1 to 100
let a = Array.init 100 (fun x -> x + 1)

//iterate over array and match *indexes* x
Array.iter (fun x ->
    match x with
        | _ when x % 15 = 0 -> printfn "FizzBuzz"
        | _ when x % 5 = 0 -> printfn "Buzz"
        | _ when x % 3 = 0 -> printfn "Fizz"
        | _ -> printfn "%d" x
) a

Это моя первая программа на F #.

Это не идеально, но я думаю, что тот, кто начинает изучать F # (как я :)), может понять, что здесь происходит довольно быстро.

Однако мне интересно, в чем разница между соответствием любому _ или самому x в сопоставлении с образцом выше?

6
задан Chad Johnson 11 June 2009 в 17:41
поделиться

5 ответов

Это немного непонятно, но может быть вариантом.

Добавьте дочерний класс для доступа к защищенной функции

public class Child extends Parent {
    public function protectedFunc() {
        return parent::protectedFunc();
    }
}

Затем создайте экземпляр Child вместо Parent , где вам нужно вызвать эту функцию.

1
ответ дан 17 December 2019 в 02:32
поделиться

I ' Я просто выбросил это, так как я не программировал на PHP два года. Не могли бы вы просто добавить в класс функцию, вызывающую защищенный метод, вот так?

$obj->publicFunc = create_function('$arg', 'return $this->protectedFunc($arg);');

Редактировать : Я думаю, что Том прав, глядя на документацию по create_function. Похоже, что область видимости $ this будет "неправильной", когда вы попытаетесь вызвать ее в этом примере.


Похоже, традиционные анонимные функции поддерживаются и с PHP 5.3.0 (и мое первое решение, вероятно, не будет работать), поэтому я бы, вероятно, написал это так:

$obj->publicFunc = function($arg) { 
     return $this->protectedFunc($arg); 
};

Поскольку я думаю, что он выглядит немного чище (и ваша выбранная IDE, конечно, выделит это лучше).


Ух, я пробовал использовать Reflection для вызова метода, но PHP также не позволит вам этого сделать. Похоже, вам придется использовать какой-то дочерний класс, как предлагали другие плакаты. Если вы найдете способ, который работает,

0
ответ дан 17 December 2019 в 02:32
поделиться

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

Это было так, когда

  • ваш класс отвечает за несколько вещей (на самом деле это два или три элемента, обернутые вместе) или
  • правила инкапсуляции нарушены (например, служебные функции)

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

0
ответ дан 17 December 2019 в 02:32
поделиться

Я думаю, что в этом случае рефакторинг, чтобы вам не требовались подобные вещи, вероятно, самый элегантный путь. Говоря, что один из вариантов - использовать __ call и внутри этого синтаксического анализа debug_backtrace , чтобы увидеть, какой класс вызвал метод. Тогда посоветуйтесь с друзьями whitelst

class ProtectedClass {

    // Friend list
    private $friends = array('secret' => array('FriendClass')); 

    protected function secret($arg1, $arg2) {
        // ...
    }

    public function __call($method, $args) {

        $trace = debug_backtrace();
        $class = $trace[1]['class'];
        if(in_array($class, $this->friends[$method]))
            return $this->$method($args[0], $args[1]);

        throw new Exception();
    }
}

Думаю, мне нужно принять душ.

3
ответ дан 17 December 2019 в 02:32
поделиться

Предположим, ваше объявление метода выглядит так:

protected function getTheFoo() {
    ...
}

protected function setTheFoo($val) {
    ...
}

Использование:

$obj->__get('the_foo');
$obj->__set('the_foo', 'myBar');

Это обходит защищенные методы и переходит прямо к переменным экземпляра.

-3
ответ дан 17 December 2019 в 02:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: