Подтвердить что ты не робот

PHP-эквивалент друга или внутреннего

Есть ли какой-то эквивалент "друга" или "внутреннего" в php? Если нет, существует ли какая-либо закономерность для достижения такого поведения?

Edit: Извините, но стандартный Php - это не то, что я ищу. Я ищу что-то вроде того, что сделал рингмейстер.

У меня есть классы, которые выполняют системные вызовы C-стиля на заднем конце, и жонглирование стало громоздким. У меня есть функции в объекте A, которые принимают в объекте B как параметр и должны вызывать метод в объекте B, проходящем в нем как аргумент. Конечный пользователь может вызвать метод в B, и система распалась.

4b9b3361

Ответ 1

PHP не поддерживает дружеские объявления. Можно моделировать это с помощью методов 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);
    }
}

(Код, доказанный tsteiner в nerdclub dot net на bugs.php.net)

Ответ 2

Также возможно повысить привилегии, а также выборочно протекать данные, используя рукопожатие и закрытие в php >= 5.3.3.

В основном происходит взаимодействие: класс A имеет открытый метод, который принимает объект класса B и вызывает B- > grantAccess (или независимо от того, что определяет ваш интерфейс), передавая ему закрытие. Закрытие use($that,$anythingelseyouneed), где $this = $this, и все, что вам нужно, чтобы определить, какие свойства разрешены для доступа. Закрытие имеет один аргумент - свойство возвращать; если это свойство на $, и все круто, замыкание возвращает свойство. В противном случае он возвращает '' или генерирует исключение или, может быть, значение по умолчанию.

Класс B- > grantAccess принимает вызываемый и сохраняет его, используя его другими способами, чтобы вырвать частные свойства, закрытие позволяет просочиться. Сделать конструктор класса B по умолчанию закрытым. Постройте B, используя статический метод factory, который принимает аргумент класса A, чтобы убедиться, что рукопожатие происходит.

Вот здесь: https://gist.github.com/mcamiano/00592fb400e5043d8acd

Ответ 3

Я уверен, что вы ищете "защищенный" или "private", в зависимости от вашего варианта использования.

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

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

Если вы определяете функцию в классе, который вы хотите использовать для классов, которые наследуются от этого класса, но недоступны публично, определенно это так:

protected function foo($arg1, $arg2)

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

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

Вам все равно придется создавать экземпляр объекта перед использованием публичной функции. Поэтому я просто буду тщательным и дам вам знать, что для использования функции в классе без создания экземпляра объекта обязательно используйте следующий синтаксис:

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

Это позволит вам использовать эту функцию, только ссылаясь на класс, следующим образом:

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

В противном случае вам нужно будет сделать следующее:

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