Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737 Форумы портала PHP.SU :: К private методам можно получить доступ даже за пределами этого объекта?
Во втором примере логика запрета доступа понятна, а вот в первом... Ведь там даже не protected метод, когда можно было бы предположить, что раз объект создан на основе такого же класса, то и доступ есть...
Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009 Откуда: Россия, Санкт-Петербург
Помог: 618 раз(а)
Доступ проверяется относительно класса, а не объекта.
В первом случае вы из класса A вызываете метод класса А - никаких проблем, потому и вызывается. И не смотрит, что объект другой.
Не помню, как к этому относятся сами разработчики PHP, но я бы не рекомендовал этим пользоваться.
like_you пишет:
при котором доступ к private методу можно получить даже вне объекта, который имеет этот метод.
Начиная с 5.4 можно штатно к любому private методу или свойству получить доступ, не имея вовсе никакого отношения к этому классу... С помощью closure::bindTo.
----- PostgreSQL DBA
like_you
Отправлено: 08 Июля, 2014 - 14:32:30
Гость
Покинул форум
Сообщений всего: 82
Дата рег-ции: Июнь 2010 Откуда: Харківська обл. с. Криштопівка
Помог: 0 раз(а)
Мелкий пишет:
Доступ проверяется относительно класса, а не объекта.
Спасибо за ответ.
Прикольно, то есть, в самом классе можно использовать приватные методы разных объектов этого же класса.
Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007 Откуда: Berlin
Помог: 707 раз(а)
Мелкий пишет:
Начиная с 5.4 можно штатно к любому private методу или свойству получить доступ, не имея вовсе никакого отношения к этому классу... С помощью closure::bindTo.
Будет работать - но это лишь частный случай уже рассмотренной выше проблемы, когда доступ проверяется на уровне текущего класса, а не конкретного экземпляра класса.
----- Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
Мелкий
Отправлено: 08 Июля, 2014 - 16:33:44
Активный участник
Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009 Откуда: Россия, Санкт-Петербург
Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007 Откуда: Berlin
Помог: 707 раз(а)
Мелкий пишет:
$c = $c->bindTo($obj, $obj);
Так тогда Вы получите привязку в контексте объекта (точнее, класса объекта) - это точно такая же "эмуляция" соответствующей области видимости. То есть - "извне" доступа всё равно не происходит, суть та же, что указана в примере выше, когда привязка происходит изнутри метода.
Вкратце - "извне" (из другого контекста) доступ получить не получится. bindTo с указанием области видимости как класса текущего экземпляра есть лишь встраивание кода замыкания в контекст этого класса.
----- Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
Мелкий
Отправлено: 08 Июля, 2014 - 16:59:49
Активный участник
Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009 Откуда: Россия, Санкт-Петербург
Помог: 618 раз(а)
Опять упираемся в терминологию?
Я под "извне" подразумевал отсутствие необходимости редактировать оригинальный код класса, но при этом прочитать/записать свойство объекта либо вызвать метод, не предназначенные для публичного доступа.
----- PostgreSQL DBA
EuGen
Отправлено: 08 Июля, 2014 - 17:04:54
Профессионал
Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007 Откуда: Berlin
Помог: 707 раз(а)
Мелкий пишет:
Я под "извне" подразумевал отсутствие необходимости редактировать оригинальный код класса, но при этом прочитать/записать свойство объекта либо вызвать метод, не предназначенные для публичного доступа.
Такая задача имеет не единственный способ решения. Начиная уже озвученными замыканиями ("наиболее изящно") и заканчивая serialize + работа со строковым результатом + unserialize. Ничего нового в этом нет. Видимо, я действительно не корректно понял значение "извне", которое Вы имели ввиду.
----- Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
teddy
Отправлено: 08 Июля, 2014 - 17:51:58
Участник
Покинул форум
Сообщений всего: 1462
Дата рег-ции: Апр. 2013
Помог: 91 раз(а)
Ещё обращение к приватному методу извне(тоже, что имел ввиду Мелкий) можно реализовать с помощью Reflection API
echo$rMethod->invoke(new MyClass,'Mike');//Hello, Mike
EuGen
Отправлено: 08 Июля, 2014 - 17:55:48
Профессионал
Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007 Откуда: Berlin
Помог: 707 раз(а)
^ If you can do something then it does not mean you should do it..
В общем - никогда не следует делать такого, не важно, замыкания это или рефлекция или что-либо другое. Это полностью ломает концепцию приватных/защищённых данных.
Это в том числе и насчёт
Мелкий пишет:
Не помню, как к этому относятся сами разработчики PHP, но я бы не рекомендовал этим пользоваться.
- то есть, совершенно правильная рекомендация так не поступать. И разработчики - да, в курсе. Но есть такие вещи, как "historically-based issues", увы.
----- Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
teddy
Отправлено: 08 Июля, 2014 - 18:02:23
Участник
Покинул форум
Сообщений всего: 1462
Дата рег-ции: Апр. 2013
Помог: 91 раз(а)
EuGen пишет:
Это полностью ломает концепцию приватных/защищённых данных.
Соглашусь
Но и возражу:
Никто в этом топике не призывает делать подобные финты. Был задан конкретный вопрос и на него были даны конкретные ответы, не более.
LIME
Отправлено: 08 Июля, 2014 - 21:59:40
Активный участник
Покинул форум
Сообщений всего: 10732
Дата рег-ции: Нояб. 2010
Помог: 322 раз(а)
У тедди что ни пост то отражения
я б их совсем запретил
Все гости форума могут просматривать этот раздел. Только зарегистрированные пользователи могут создавать новые темы в этом разделе. Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.