Pertanyaan PHP setara dengan teman atau internal


Apakah ada yang setara dengan "teman" atau "internal" di php? Jika tidak, apakah ada pola untuk diikuti untuk mencapai perilaku ini?

Edit: Maaf, tapi Php standar bukan yang saya cari. Saya mencari sesuatu di sepanjang garis dari apa yang dilakukan oleh para pemimpin sirkus.

Saya memiliki kelas yang melakukan panggilan sistem C-gaya di bagian belakang dan juggling telah mulai menjadi rumit. Saya memiliki fungsi dalam objek A yang mengambil objek B sebagai parameter dan harus memanggil metode dalam objek B lewat dirinya sebagai argumen. Pengguna akhir dapat memanggil metode dalam B dan sistem akan berantakan.


28
2017-11-25 16:00


asal


Jawaban:


PHP tidak mendukung deklarasi seperti teman. Ini mungkin untuk mensimulasikan ini menggunakan metode PHP5 __get dan __set dan memeriksa backtrace hanya untuk kelas teman yang diizinkan, meskipun kode untuk melakukannya agak canggung.

Ada beberapa Kode sampel dan diskusi tentang topik di situs 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);
    }
}

(Kode dibuktikan oleh tsteiner di nerdclub dot net di bugs.php.net)


40
2017-11-25 16:14



Juga dimungkinkan untuk meningkatkan privileges, alias membocorkan data secara selektif, menggunakan jabat tangan dan penutupan dalam php> = 5.3.3.

Pada dasarnya, interaksi berjalan: kelas A memiliki metode publik yang menerima objek kelas B, dan memanggil B-> grantAccess (atau apa pun yang didefinisikan oleh antarmuka Anda), melewatkannya sebagai penutupan. Penutupan use($that,$anythingelseyouneed) di mana $ that = $ this, dan apa pun yang Anda perlukan untuk menentukan properti apa yang diizinkan untuk diakses. Penutupan itu memiliki satu argumen - properti untuk kembali; jika itu adalah properti di $ itu dan semuanya keren, penutupan mengembalikan properti. Jika tidak, ia mengembalikan '', atau melempar pengecualian, atau mungkin nilai default.

Kelas B-> grantAccess menerima callable dan menyimpannya, menggunakannya dalam metode lain untuk mencabut properti pribadi yang memungkinkan penutupan bocor. Jadikan konstruktor default kelas B. Buatlah B menggunakan metode pabrik statis yang mengambil argumen Kelas A, untuk memastikan jabat tangan terjadi.

Intinya di sini: https://gist.github.com/mcamiano/00592fb400e5043d8acd


7
2017-08-08 00:45



Saya sangat yakin apa yang Anda cari adalah "dilindungi" atau "pribadi", tergantung pada kasus penggunaan Anda.

Jika Anda mendefinisikan suatu fungsi di kelas, dan Anda hanya menginginkan suatu fungsi untuk kelas itu sendiri, Anda akan mendefinisikannya seperti ini:

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

Jika Anda mendefinisikan suatu fungsi di kelas yang ingin Anda sediakan untuk kelas yang mewarisi dari kelas ini, tetapi tidak tersedia untuk umum, definisikan dengan cara ini:

protected function foo($arg1, $arg2)

Saya cukup yakin bahwa secara default di PHP5, fungsinya bersifat publik, yang berarti Anda tidak perlu menggunakan sintaks berikut, tetapi ini opsional:

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

Anda masih harus melakukan instantiate objek sebelum menggunakan fungsi publik. Jadi saya hanya akan teliti dan memberi tahu Anda bahwa untuk menggunakan fungsi di kelas tanpa instantiate objek, pastikan untuk menggunakan sintaks berikut:

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

Itu akan memungkinkan Anda untuk menggunakan fungsi dengan hanya mereferensikan kelas, sebagai berikut:

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

Jika tidak, Anda perlu melakukan hal-hal berikut:

$myObject = new MyClass();
$myObject->foo($a1, $a2);

-14
2017-11-25 16:09