PHP-эквивалент друга или внутреннего
Есть ли какой-то эквивалент "друга" или "внутреннего" в php? Если нет, существует ли какая-либо закономерность для достижения такого поведения?
Edit:
Извините, но стандартный Php - это не то, что я ищу. Я ищу что-то вроде того, что сделал рингмейстер.
У меня есть классы, которые выполняют системные вызовы C-стиля на заднем конце, и жонглирование стало громоздким. У меня есть функции в объекте A, которые принимают в объекте B как параметр и должны вызывать метод в объекте B, проходящем в нем как аргумент. Конечный пользователь может вызвать метод в B, и система распалась.
Ответы
Ответ 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);