36

PHPに「友人」または「内部」に相当するものはありますか? そうでない場合、この動作を実現するために従うべきパターンはありますか?

編集: 申し訳ありませんが、標準の PHP は私が探しているものではありません。リングマスターがやったことの線に沿って何かを探しています。

バックエンドで C スタイルのシステム コールを実行しているクラスがあり、ジャグリングが面倒になり始めています。オブジェクト A には、オブジェクト B をパラメーターとして取り、それ自体を引数として渡すオブジェクト B のメソッドを呼び出す必要がある関数があります。エンド ユーザーが B のメソッドを呼び出すと、システムが崩壊する可能性があります。

4

5 に答える 5

47

PHP は、friend-like 宣言をサポートしていません。PHP5 の __get および __set メソッドを使用して、許可されたフレンド クラスのみのバックトレースを検査することで、これをシミュレートすることができます。

PHP のサイトには、このトピックに関するサンプル コードとディスカッションがあります。

class HasFriends
{
    private $__friends = array('MyFriend', 'OtherFriend');

    public function __get($key)
    {
        $trace = debug_backtrace();
        if(isset($trace[1]['class']) && in_array($trace[1]['class'], $this->__friends)) {
            return $this->$key;
        }

        // normal __get() code here

        trigger_error('Cannot access private property ' . __CLASS__ . '::$' . $key, E_USER_ERROR);
    }

    public function __set($key, $value)
    {
        $trace = debug_backtrace();
        if(isset($trace[1]['class']) && in_array($trace[1]['class'], $this->__friends)) {
            return $this->$key = $value;
        }

        // normal __set() code here

        trigger_error('Cannot access private property ' . __CLASS__ . '::$' . $key, E_USER_ERROR);
    }
}

(コードは、bugs.php.net の nerdclub dot net で tsteiner によって証明されまし)

于 2008-11-25T16:14:08.107 に答える
-19

ユースケースに応じて、探しているものが「保護」または「プライベート」であると確信しています。

クラスで関数を定義していて、その関数をそれ自体でのみ使用できるようにする場合は、次のように定義します。

private function foo($arg1, $arg2) { /*function stuff goes here */ }

このクラスから継承するクラスで使用できるようにしたいが、パブリックには使用できないクラスで関数を定義している場合は、次のように定義します。

protected function foo($arg1, $arg2)

PHP5 のデフォルトでは、関数は public であると確信しています。つまり、次の構文を使用する必要はありませんが、オプションです。

public function foo($arg1, $arg2) { /*function stuff goes here */ }

public 関数を使用する前に、オブジェクトをインスタンス化する必要があります。オブジェクトをインスタンス化せずにクラスで関数を使用するには、必ず次の構文を使用してください。

static function foo($arg1, $arg2) { /*function stuff goes here */ }

これにより、次のようにクラスを参照するだけで関数を使用できるようになります。

MyClass::foo($a1, $a2);

それ以外の場合は、次の操作を行う必要があります。

$myObject = new MyClass();
$myObject->foo($a1, $a2);
于 2008-11-25T16:09:55.087 に答える