Реализации read-only свойств в классах.

Бочонок

http://frontender.info
Реализации read-only свойств в классах.

Приятного времени суток.

Столкнулся с задачей реализации read-only свойств в классах.

Сделал просто и понятно:
PHP:
class testClass{	

	protected $albumCollection = 'Я могу считать это значение, но не могу записать.';
	protected $photoCollection = 'Read only';
	
	public function getAlbumCollection(){
		return $this->albumCollection;
	}
	public function getPhotoCollection(){
		return $this->photoCollection;
	}
}
Но, когда мой код рецензировал некий программист, работающий в Яндекс (за что ему огромное спасибо), он написал:
Неясно зачем столько методов с префиксом «get», вместо этого можно использовать магические методы, если почему-то не хочется давать прямой доступ к свойствам.
Ну ... в общем то это не большая проблема. Написал:
PHP:
class testClass{	

	protected $albumCollection = 'Я могу считать это значение, но не могу записать.';
	protected $photoCollection = 'Read only';
	
	public function __get($name){
		return $this->$name;
	}
}
А как тогда защитить те свойства, которые не нужно позволять читать? Вот таким вот извращенным методом?

PHP:
class testClass{	
	private $hidden = array('photoCollection');
	protected $albumCollection = 'Я могу считать это значение, но не могу записать.';
	protected $photoCollection = 'Read only';
	
	public function __get($name){
		if (in_array($name,$hidden)) throw new Exception("А нету!", E_ERROR);
		return $this->$name;
	}
}
В общем, я в задумчивости. Подскажите, пожалуйста, как лучше сделать?
Может быть я что то вообще не то делаю?

С уважением. Боченок.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
в яндексе не телепаты работают - он просто не понял потому что ты не потрудился написать комментарий в коде, что-то вроде
PHP:
/**
 * @var $albumCollection string 
 * @access readonly
 */
    protected $albumCollection = 'Я могу считать это значение, но не могу записать.';
-~{}~ 01.04.10 20:03:

а "прямой доступ к свойствам" - это вечный холивар
в некоторых талмудах по ООП прямо пишут, что публичные поля недопустимы
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
теории тут нет, к слову

-~{}~ 01.04.10 20:07:

Автор оригинала: Бочонок
2grigori весь код комментирован.
Видимо, у тебя постоянные сбои коммуникации.
 

Бочонок

http://frontender.info
Почему же нету?
Вроде бы как раз теория.
Рассматривается проблема в целом а не решение конкретной задачи.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
почитай для начала правила составления вопросов на этом форуме
http://phpclub.ru/talk/showthread.php?s=&threadid=28522&rand=1
"Код, в котором возникает ошибка, тоже копируйте"
 

Бочонок

http://frontender.info
Кстати,
Вообще то
@access private|protected|public

http://manual.phpdoc.org/HTMLframesConverter/default/phpDocumentor/tutorial_tags.access.pkg.html

-~{}~ 01.04.10 21:12:

Код не содержит ошибок. И то и другое решение работает.
Проблема на уровне теории.
 

Духовность™

Продвинутый новичок
Неясно зачем столько методов с префиксом «get», вместо этого можно использовать магические методы, если почему-то не хочется давать прямой доступ к свойствам.
Магические методы не надо совать туда, куда не нужно. Если класс динамически создается и является в некоторым смысле хранилищем данных, то да - магические методы нужны.

А если в твоем классе ограниченный набор каких-то свойств, без которых класс будет попросту не рабочим, то лично я не вижу причин не использовать геттеры. Наоборот, в данном случаи они нужны, как важнейшая часть инфраструктуры класса. И шаманством с __magic в данном случае обходиться не надо.

Приведи контекст задачи своей.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
"Вообще-то" комментарии пишутся для людей, а не для "phpdoc valid!".

Вопрос "как тогда защитить те свойства, которые не нужно позволять читать" надо задать человеку, который высказал мнение о том, что это неправильно.
Я мысли читать не умею.
 

Бочонок

http://frontender.info
2triumvirat: спасибо большое за ответ.
Контекст:

Я написал библиотеку, которая работает с сервисом API Яндекс.Фотки. И постепенно "вылизываю" ее код, исправляя те минусы, которые нашел сам и на которые указали окружающие.

Пример свойства, которое не имеет смысла разрешать записывать:
У класса, обеспечивающего работу с фотографиями есть свойство "время создания". Оно получается из XML, который вернул сервис Яндекс и как то его изменить нельзя. Так зачем давать к нему доступ?
На мой взгляд, чем точнее определено поведение классов и обеспечиваемые им функциональные возможности тем лучше.

http://code.websaints.net/ - библиотека в текущем ее состоянии.

2grigori:
Для того, что бы сказать как бы вы поступили, если бы вам было необходимо обеспечить доступ к свойствам "только для чтения" вам вовсе не нужно уметь читать мысли. Мне интересны только ваши мысли по этому поводу.
 

Fortop

Новичок
Мгм, а в чем вообще вопрос?

Хотите сделать свойство readonly?
Или writeonly (как показано в коде)?

В любом случае вместо "нету" лучше давать конкретное сообщение об ошибке
PHP:
Exception('property read-/writeonly');
-~{}~ 01.04.10 20:33:

Код:
phpDoc
 * @property-read
 * @property-write
-~{}~ 01.04.10 20:38:

работающий в Яндекс (за что ему огромное спасибо)
Бгг, порадовало :) Спасибо ему за то, что он работает в Яндексе...
 

Krishna

Продался Java
Но, когда мой код рецензировал некий программист, работающий в Яндекс (за что ему огромное спасибо), он написал:
Яндекс, при всём к нему уважении, как к качественному продукту и удачному бизнесу - с точки зрения программиста (по инсайдерской и не очень информации) это макдональндс, где работают "за еду" (ниже рынка, если конкретно), ради опыта и ради пафоса, чтобы потом с умным видом писать вот такую феерическую х*%ню, что он написал, ну и устроиться потом в контору, где нормально платят :)

Писать геттеры/сеттеры это как минимум не зазорно, а, имхо, и вообще хорошо и правильно. Писать геттеры, когда надо обеспечить r/o - вообще труЪ.

А волшебный метод задуман для более хитрых случаев.
В данном случае от него будет один гемор, начиная с того, о котором ты сам написал.
 

Бочонок

http://frontender.info
2Fortop ну, вообще-то, спасибо что потратил время на мой код.
А почему
Или writeonly (как показано в коде)?
?

Свойства в код неполучится записать.

2Fortop:
phpDoc
* @property-read
* @property-write
Помоему это немножко не то.
http://manual.phpdoc.org/HTMLframesConverter/earthli/phpDocumentor/tutorial_tags.property.pkg.html
 

Fortop

Новичок
Ну в коде магический метод __get не дает читать некоторые свойства :)
Значит они явно не read
 

Бочонок

http://frontender.info
2Krishna: Спасибо большое.
Похоже магические методы __get я приберегу для всяких хитрых враперов.
 

Fortop

Новичок
readonly = только для чтения. Т.е. только __get
writeonly = только для записи. Т.е. только __set

-~{}~ 01.04.10 20:47:

А волшебный метод задуман для более хитрых случаев.
Например? :)
 

Бочонок

http://frontender.info
Автор оригинала: Fortop
Ну в коде магический метод __get не дает читать некоторые свойства :)
Значит они явно не read
Ну ... не знаю ... записать свойства в вышеуказанном коде вообще не получится.
 

Krishna

Продался Java
Ну, например динамически их создавать, предоставляя таким образом адаптер для доступа к необъектной структуре, например полям внешнего документа, который представляет объект.

А вообще, такие средства, как магические методы, рефлексия и тп - больше всего подходят для создания фреймворков и либ, нежели прикладного программирования. Я даже их применял в своём проекте подобным образом, но это слишком сильно потребует выйти за рамки обсуждения, чтобы приводить, как пример.

Прикладной код должен быть максимально нагляден и самодокументируем. Волшебные методы этому никак не способствуют, в частности вызывают проблему при работе с IDE
 

Бочонок

http://frontender.info
Сверху