Intereting Posts
Bootstrap Кнопка загрузки состояния загрузки JQuery, как заставить другие состояния делать то же самое PHP Сессионное хранилище глобально для всех пользователей преобразовать часть элемента dom в строку с тегами html внутри них Как перенести элемент массива с известным ключом в конец массива в PHP? Увеличение дней до текущей текущей даты () PHP. Рекурсивно перечислять все каталоги и подкаталоги в выпадающем меню Как получить именно идентификатор последней вставленной записи в mysql? Простой способ отправки электронной почты с помощью javascript и PHP Может ли клиент просмотреть исходный код PHP на стороне сервера? Выходной буфер PHP не промывается PHP Curl не хранит эхо-данные json_encoded Запуск приложения Windows Speech SDK в PHP Joomla 3.2 Сгруппированный список Пользовательский список полей не имеет значения SELECTED Автоматический формат Aptana Как проверить целочисленные значения, чтобы избежать SQL-инъекций?

Как сделать переменную приватной для черты?

Я хотел бы повторно использовать функциональность несколько раз в одном классе. Эта функция зависит от частной переменной:

trait Address { private $address; public function getAddress() { return $this->address; } public function setAddress($address) { $this->address = $address; } } 

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

 class User { use Address { getAddress as getHomeAddress; setAddress as setHomeAddress; getAddress as getWorkAddress; setAddress as setWorkAddress; } } 

Проблема заключается в том, что при этом приватная переменная $address разделяется между различными методами, и код не будет работать должным образом:

 $user = new User(); $user->setHomeAddress('21 Jump Street'); echo $user->getWorkAddress(); // 21 Jump Street 

Есть ли решение действительно использовать этот признак дважды, не разделяя его частных переменных?

Объявление признака с use не создаст экземпляр этой черты. Черты – это просто код, который копируется и вставляется в класс использования. Как только будет создан псевдоним для этого метода, например, он добавит что-то вроде

 public function getHomeAddress() { return $this->getAddress(); } 

к вашему классу User. Но это будет только одна черта. Не будет двух разных $address свойств, но только одного.

Вы можете сделать методы частными, а затем делегировать любые публичные вызовы ему через __call помощью switch / __call на имя метода и использовать массив для адреса, например

 trait Address { private $address = array(); private function getAddress($type) { return $this->address[$type]; } private function setAddress($type, $address) { $this->address[$type] = $address; } public function __call($method, $args) { switch ($method) { case 'setHomeAddress': return $this->setAddress('home', $args[0]); // more cases … } } } 

Но это всего лишь банда червей.

Другими словами, вы не можете разумно делать то, что вы пытаетесь сделать с чертами. Либо используйте две разные черты. Или используйте хорошую старую агрегацию и добавьте конкретные прокси-методы.

Я подтвердил, что вы можете использовать одну и ту же функцию несколько раз, что было для меня неожиданностью. Несмотря на то, что ZendStudio появляется только «помощник кода» в последнем псевдониме функции.

Возможность множественной псевдонимы одной и той же функции несколько раз могла окунуться в какое-то интересное поведение, если функция Trait может определить, какое имя она называлась. Но, похоже, мы не можем определить функцию «сглаживания» в функции признаков.

Вот мой тестовый код:

 <?php trait TestTrait { public function test() { print __CLASS__ . ', ' . __TRAIT__ . ', ' . __METHOD__ . ', ' . __FUNCTION__ . "\n"; } } class TestClass { use TestTrait { test as test1; test as test2; } } $c = new TestClass(); $c->test1(); $c->test2(); 

Вывод:

 TestClass, TestTrait, TestTrait::test, test TestClass, TestTrait, TestTrait::test, test 

Возможно, было бы неплохо добавить новую константу ALIAS для функций признаков, чтобы определить, какой псевдоним они были вызваны.

На самом деле я создал PHP-запрос функции для этого:

https://bugs.php.net/bug.php?id=63629

я могу немного опоздать на вечеринку, но поведение, которое вы пытаетесь создать, не является чем-то, что должно быть покрыто чертой, а простой композицией объекта.

 <?php class Adddress { private $street; private $number; public function __construct(string $street, ?string $number) {} public function street() : string {} public function number() : string {} } class User { private $homeAddress; private $workAddress; public function getHomeAddress() : Address {} public function setHomeAddress(Address $homeAddress) : self {} public function getWorkAddress() : Address {} public function setWorkAddress(Address $workAddress) : self {} }