8

クラスの外部から保護されたメソッドを呼び出す必要がある非常に特殊なケースがあります。私はプログラミング的に何をするかについて非常に意識していますが、私が持っているこの1つの特別なケースでは、そうすることに完全に反対するつもりはありません. それ以外の場合はすべて、内部メソッドへのアクセスを引き続き禁止する必要があるため、メソッドを保護したままにします。

クラス外で保護されたメソッドにアクセスするエレガントな方法は何ですか? これまでのところ、私はこれを見つけまし

内部へのアクセスを密かに提供する、ターゲットクラスのある種の二重エージェントインスタンスを作成できる可能性があると思います...

4

6 に答える 6

7

PHP では、リフレクションを使用してこれを行うことができます。保護されたメソッドまたはプライベート メソッドを呼び出すには、setAccessible() メソッド http://php.net/reflectionmethod.setaccessibleを使用します ( TRUE に設定するだけです) 。

于 2011-09-06T13:38:23.853 に答える
4

この場合、この種のことを必要としないようにリファクタリングすることが、おそらく最もエレガントな方法だと思います。1 つのオプションは、__callその解析内で andを使用しdebug_backtraceて、どのクラスがメソッドを呼び出したかを確認することです。次に、友達のホワイトリストを確認します

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();
    }
}

シャワーが必要だと思います。

于 2009-06-11T21:45:25.503 に答える
1

これは少し厄介ですが、オプションになる可能性があります。

保護された関数にアクセスするために子クラスを追加します

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

次に、その関数を呼び出す必要がある場所のChild代わりにインスタンスをインスタンス化します。Parent

于 2009-06-11T18:51:00.260 に答える
0

私は2年間PHPでプログラミングしていないので、これを捨てています。そのように保護されたメソッドを呼び出すクラスに関数を追加していただけませんか?

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

編集: create_function のドキュメントを見て、Tom は正しいと思います。この例で呼び出そうとすると、 $this のスコープが「間違っている」ように見えます。


従来の匿名関数も PHP 5.3.0 以降でサポートされているようです (そして、私の最初の解決策はおそらく機能しないでしょう)。そのため、代わりに次のように記述します。

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

私はそれが少しきれいに見えると思うので(もちろん、選択したIDEはそれをよりよく強調します)。


うーん、リフレクションを使用してメソッドを呼び出してみましたが、PHP でもそれができません。他のポスターが示唆しているように、ある種の子クラスを使用する必要があるようです。機能するメソッドが見つかった場合、開発者は将来それをバグとして分類し、次のバージョンにアップグレードしたときにコードを壊す可能性があります。

クラスの延長をお勧めします。

于 2009-06-11T17:42:32.810 に答える
0

プライベート関数を呼び出さなければならない場合、プログラムの設計に問題があると思いますか?

かつてはそうでした

  • あなたのクラスはいくつかのことを担当しています(実際には2つまたは3つのクラスが一緒にラップされています)または
  • カプセル化のルールが破られている (ユーティリティ関数など)

この問題を回避する方法を見つけたとしても、本当の解決策に近づくことはできません。

于 2009-06-12T11:03:38.347 に答える
-3

メソッド宣言が次のようになったとします。

protected function getTheFoo() {
    ...
}

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

使用法:

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

これにより、保護されたメソッドがバイパスされ、インスタンス変数に直接移動します。

于 2010-03-30T14:20:37.133 に答える