Как лучше организовать доступ к элементам класса?

dimitrius

Новичок
В литературе рекомендуют через сет и гет.
В реализации классов на сайте pear в основном используется прямой доступ?
Я склоняюсь к первому варианту, и тогда в методах класса считаю элементы проверенными и безопасными
А вы что скажите?
 

Dovg

Продвинутый новичок
Обращение изнутри класса к свойстам через геттеры позволяет более просто проводить модификации - при изменении способа хранения данных править придется только геттер.
 

fixxxer

К.О.
Партнер клуба
Если возникает такой вопрос, то в первую очередь следует подумать, как изменить архитектуру, чтобы не надо было узнавать свойства класса напрямую. :)

Простой пример - если $User->id == 0 - это гость, заменить проверку $User->id на $User->isGuest()
 

dimitrius

Новичок
Если возникает такой вопрос, то в первую очередь следует подумать, как изменить архитектуру, чтобы не надо было узнавать свойства класса напрямую. :)

Простой пример - если $User->id == 0 - это гость, заменить проверку $User->id на $User->isGuest()
Спасибо.
 

scorpion-ds

Новичок
Я пытался пользоваться встроенными сетерами и гетерами, но мне не понравилось: во-первых Zend Studio в таком случае не делает подсказки по классам, во-вторых у менять часто есть необходимость проверять передаваемые данные (это для сетеров), потому для свойств классов которые надо менять извне я создают отдельные функции, то же самое для получения значений этих свойств.
 

Духовность™

Продвинутый новичок
Я пытался пользоваться встроенными сетерами и гетерами, но мне не понравилось: во-первых Zend Studio в таком случае не делает подсказки по классам, во-вторых у менять часто есть необходимость проверять передаваемые данные (это для сетеров), потому для свойств классов которые надо менять извне я создают отдельные функции, то же самое для получения значений этих свойств.
// 1. С помощью call можно иммитировать методы setVariableName().
// Т.е. метода setVariableName() нет, а переменная в классе есть. Для этого нужно просто описать в классе, какие его члены должны иметь виртуальные методы.
// 2. Когда тебе нужно "проверять передаваемые данные"? то можно создавать реальые методы или методы, которые бы назывались, например, с подчеркивания и вызывались бы в нутри виртуальны методов.
 

Духовность™

Продвинутый новичок
Смотри как у меня:

PHP:
    /**
     * Получение и установка свойств объекта через вызов магического метода вида:
     *
     * $model->(get|set)PropertyName($prop);
     *
     * @see __call
     * @return mixed
     */
    public function __call($method_name, $argument)
    {
        $args = preg_split('/(?<=\w)(?=[A-Z])/', $method_name);

        $action = array_shift($args);

        $property_name = strtolower(implode('_', $args));

        if (!isset(static::$model_attributes[$property_name]))
        {
        	throw new BadMethodCallException(
                __CLASS__ . '::' . __METHOD__ . ': Вызов неизвестного метода ' . get_class($this) . '::' . $method_name
            );
        }

        switch ($action)
        {
            case 'get':
                return $this->$property_name;

            case 'set':
                $this->$property_name = $argument[0];

                $has_errors = isset($this->validate_errors[$property_name]);

                $explicit_method = '_' . $method_name;

                // Смотрим, имеется ли в классе явно объявленный set-метод (с префиксом "_") для
                // данного свойства и имеются ли ошибки валидации.
                // Если метод явно объявлен, а ошибок валидации нет, то применяем метод
                // для текущего состояния свойства.
                // Данные методы, с префиксом '_' в модели нужны для ситуаций, когда при присвоении объекту значений
                // необходимо обработать значение с помощью какой-либо логики.
                // Как пример, можно посмотреть метод Krugozor_Module_User_Model_User::_setUrl
                if (method_exists($this, $explicit_method) && !$has_errors)
                {
                   $this->data[$property_name] = $this->$explicit_method($this->$property_name);
                }

                return $this;
        }
    }
 

scorpion-ds

Новичок
Духовность™
Спасибо, я примерно так уже делал, вот только не проверял есть ли "метод валидации", а просто создавал его, ведь всегда сначала ищется реально существующий метод, а потом только вызывается "__call".

По большей части я оказался от использования сетеров и геторов, потому что не создавались подсказки для zend studio (или аналогов), Dovg выше написал, что это можно сделать применяя phpdoc, но я пока не понял как. Я и так к методам обычно добавляю правильно оформленные комментарии, но как делать эти комментарии к "виртуальным" методам я не понял, ну я и не углублялся в изучение phpdoc.
 

fixxxer

К.О.
Партнер клуба
Что это за архитектура, блин, такая, что надо столько геттеров и сеттеров, что под них хитрые обертки пишутся? И главное зачем? Уж юзайте тогда public да и всё. Один же хрен.

(Не, я понимаю, если это базовый класс модели, там нормально, да).
 

stopkran

Дилетант
Простой пример - если $User->id == 0 - это гость, заменить проверку $User->id на $User->isGuest()
А что делать если статусов несколько? Например:

$id == 1 //автор
$id == 2 //редактор
$id == 3 //админ
$id == 4 //программист

проверять всех как if ($User->isAdmin()), else if ($User->isAuthor()), ... ?
 

scorpion-ds

Новичок
stopkran
можно просто код с типом пользователя возвращать, хотя можно сделать так как и ты в примере.
 

Adelf

Administrator
Команда форума
А что делать если статусов несколько? Например:

$id == 1 //автор
$id == 2 //редактор
$id == 3 //админ
$id == 4 //программист

проверять всех как if ($User->isAdmin()), else if ($User->isAuthor()), ... ?
Имхо, код не должен знать программист там юзер или админ. Должен он лишь уметь проверить есть ли у данного юзера права на такие то действия или нет.
 
  • Like
Реакции: AmdY

С.

Продвинутый новичок
Имхо, код не должен знать программист там юзер или админ. Должен он лишь уметь проверить есть ли у данного юзера права на такие то действия или нет.
Какая принципиальная разница между
PHP:
$user->isAdmin()
и
PHP:
$user->isRole(USER_ADMIN)
?

В программе не может быть неопределнного количества неопредеделенных ролей. Этих ролей конечное множество и они прошиваются на уровне алгоритма.
 

Adelf

Administrator
Команда форума
В программе не может быть неопределнного количества неопредеделенных ролей. Этих ролей конечное множество и они прошиваются на уровне алгоритма.
Программа программе рознь. Опять таки, имхо, определение того, имеет право юзер на это действие или нет - это отдельная задача и реализована она должна быть отдельно(как в любом нормально спроектированном приложении). Будь это ACL там или попроще(посложнее?) - это отдельная задача и сам алгоритм должен знать об этом как можно меньше.

Upd: И да, есть такие программы, в которых число ролей очень велико и настраивается отдельно. Писал медицинский софт - там с этим сложно. Главврач может то-то. Лаборанты - то-то. Обычные врачи, работники регистратуры и т.д. и т.п.
Ты действительно думаешь, что в этом случае тоже правильно было бы на уровне алгоритмов там решать, имея знания о каждой из ролей?
 
  • Like
Реакции: Gas

Духовность™

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