Каков наилучший способ хранения атрибутов класса PHP? - PullRequest
4 голосов
/ 30 апреля 2009

Дубликат: Каков наилучший способ хранения переменных класса в PHP?

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

Итак, какой из них, по вашему мнению, следует использовать? Примерно так:

Class test{
    public $attr1;
    public $attr2;
    .............. 
    public function __construct(){
        $this->attr1 = val;  
        $this->attr1 = val;
        ...................   
    }
}

Versus:

Class test{
    public $data;

    public function __construct(){
        $this->data['attr1'] = val;
        $this->data['attr2'] = val;
        ..........................       
    }
}

Это важно, когда у вас есть объекты со многими атрибутами, которые нужно часто хранить и извлекать из них.

Также важно, когда вы имеете дело с объектами со многими атрибутами, используете ли вы геттеры и сеттеры для каждого атрибута или скорее один метод для установки всех и один метод для получения всех?

Ответы [ 8 ]

9 голосов
/ 30 апреля 2009

Версия 1 - более «классический» способ ведения дел. Ваш объект в точности такой, как вы говорите.

Я не могу сказать, что строго «лучше», но могу сказать, что мне удобнее.

Я использовал вторую версию (обычно для моделей баз данных в CodeIgniter, и особенно на ранних этапах разработки) в сочетании с пользовательскими методами получения и установки PHP5 для динамической перегрузки класса. т.е.

<?php
    class foo{
        private $data = array();

        function __construct()
        {
            # code...
        }

        public function __get($member) {
            if (isset($this->data[$member])) {
                return $this->data[$member];
            }
        }

        public function __set($member, $value) {
            // The ID of the dataset is read-only
            if ($member == "id") {
                return;
            }
            if (isset($this->data[$member])) {
                $this->data[$member] = $value;
            }
        }
    }

    $bar = new foo()
    $bar->propertyDoesntExist = "this is a test";
    echo $bar->propertyDoesntExist; //outputs "this is a test"
?>
5 голосов
/ 30 апреля 2009

Я бы использовал вторую версию тогда и только тогда, когда данные получены целиком из внешнего источника (например, запрос BD). В этом случае, конечно, рекомендуется иметь общий __get() / __set() для доступа к $this->data. Вы также можете рассмотреть возможность реализации интерфейса IteratorAggregate , возвращающего new ArrayIterator($this->data).

1 голос
/ 30 апреля 2009

Первый метод довольно стандартный. Он четко определяет свойства и позволяет IDE и инструментам документирования кода выбирать доступные свойства объекта.

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

Я бы никогда не рекомендовал использовать второй метод для публичного свойства, поскольку он демонстрирует отсутствие понимания свойств объекта и области видимости переменных и может привести к проблемам в коде (что, если кто-то перезапишет этот корневой массив строкой? )

Использование методов получения и установки позволяет использовать свойства, которые необходимо изменить в вызывающем коде. Не каждое свойство должно быть доступным, так что это зависит от разработчика, определяющего объект. Шаблон getter / setter не имеет смысла для общедоступных свойств, очевидно, но он имеет значение для защищенных и приватных свойств, которые могут нуждаться в некоторой проверке или быть очищенными. Они также имеют смысл в контексте внедрения зависимостей.

1 голос
/ 30 апреля 2009

Если нет действительно убедительных аргументов для какой-либо версии (в зависимости от контекста), я всегда выбирал формат, который позволяет моим ide / tools предоставлять более полную информацию о типах, классах, отношениях и т. Д., И до сих пор это первый формат .
Есть и другие способы доступа к данным «в виде массива».

0 голосов
/ 18 ноября 2010

Лучший метод наверняка стандартный, а второй, безусловно, более удобный ...

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

    public function GET__Attributes_in_Array(){
     $Prova = get_class_vars(get_class($this));
     print_r($Prova);

     return $Prova;
}

Эта функция возвращает вам массив со всеми атрибутами и значением класса ...

0 голосов
/ 30 апреля 2009

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

0 голосов
/ 30 апреля 2009

Я бы тоже предпочел версию 1. Если вам не нужны динамические участники (версия, предоставленная Крисом), вам следует определить своих участников. Динамический путь приводит в большинстве случаев к ужасной конструкции, которая затрудняет понимание вашего кода. Представьте, что кому-то может понадобиться отладить ваш код и он не знает ваш код ^^. У нас есть более крупный проект, который использует динамические элементы для зеркального отображения полей в таблице базы данных. Его довольно сложно использовать, не зная таблицы.

Кроме того, что ваша IDE не работает с dyn. члены, вы не можете использовать PHPDoc для этих членов, а PHPUnit не может использовать Reflection для этих атрибутов. Это просто плохой стиль кодирования.

С уважением, Mario

0 голосов
/ 30 апреля 2009

лично я использую версию 1, потому что я думаю, что она более правильная, поддерживает автозаполнение в IDE и облегчает отладку.

Я также использую геттеры и сеттеры почти для всех моих переменных-членов (которые я определяю как закрытые / защищенные большую часть времени), потому что установка одного значения вызывает изменения в других значениях очень часто. Одним из недостатков создания g & s является огромное количество уродливого, глупого кода, который накапливается с течением времени, если вы определяете получатели / установщики даже для атрибутов, которые не инициируют изменения в другом месте. я все еще делаю это для непротиворечивого интерфейса - я никогда не знаю, когда я представляю дополнительную функциональность или исправления ошибок, которые вводят больше изменений на наборе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...