Подскажите по примеру блога

подскажите по такому фрагменту:


class Lookup extends CActiveRecord

{

    private static $_items=array();

 

    public static function items($type)

    {

        if(!isset(self::$_items[$type]))

            self::loadItems($type);

        return self::$_items[$type];

    }

 

    public static function item($type,$code)

    {

        if(!isset(self::$_items[$type]))

            self::loadItems($type);

        return isset(self::$_items[$type][$code]) ? self::$_items[$type][$code] : false;

    }

 

    private static function loadItems($type)

    {

        self::$_items[$type]=array();

        $models=self::model()->findAll(array(

            'condition'=>'type=:type',

            'params'=>array(':type'=>$type),

            'order'=>'position',

        ));

        foreach($models as $model)

            self::$_items[$type][$model->code]=$model->name;

    }

}

а именно строки типа


if(!isset(self::$_items[$type]))

не совсем непонятно зачем проверять на существование self::$_items?

Судя по приведенному коду - если self::$_items[$type] уже существует, то вызов функции loadItems($type)

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

Ну наверно что бы избежать повторный запрос к базе.

Изучаю я потихоньку исходные коды yii и не устаю восхищаться мастерству создателей.

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

Обратите внимание - нигде ведь не создается экземпляр объекта этого класса.

В то же время статическая переменная


private static $_items=array();



доступна в любое время из любого места программы, достаточно вызвать один из двух

статических методов. А самое главное она заполняется данными из базы данных всего один раз-при

самом первом вызове - и все, далее бери ее в любое время, из любого места, где находишься !

[b]То есть класс, голый, сам по себе(без экземпляров) представляет этакий склад,

причем, охраняемый-переменные имеют тип private, с автоматизированной

подачей запрошенного товара.[/b]


Извиняюсь за лирическое отступление, просто я сам во всех этих делах новичек и очень

рад хорошему учебному материалу.


да все понятно. теперь про другое но из тогоже примера блога. есть вот такой код:




protected function beforeSave()

{

    if(parent::beforeSave())

    {

        if($this->isNewRecord)

        {

            $this->create_time=$this->update_time=time();

            $this->author_id=Yii::app()->user->id;

        }

        else

            $this->update_time=time();

        return true;

    }

    else

        return false;

}




и далее




protected function afterSave()

{

    parent::afterSave();

    Tag::model()->updateFrequency($this->_oldTags, $this->tags);

}




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

может кто-то пролить свет

Если я правильно понимаю, если beforeSave возвращает false сохранение данных не происходит, поэтому проверяется что возвращает родительский метод, а родительский метод запускает onBeforeSave события повидений (behaviors). А в методе afterSave это не требуется

непонятно именно что он такого делает что надо проверять beforeSave. скорее логичнее сделать наоброт:

  • beforeSave без проверки на ложь

  • afterSave с прверкой на ложь: вдруг не сохранилось и таг некуда будет писать

вот как было бы понятнее или перефразируя: зачем проверять до сохранения - лучше после сохранения

Во фреймворке есть такие такие штуки как поведения behaviors, можно написать процедуры которые будут повторно использоваться в нескольких моделях. При выполнении поведения в котором есть событие onBeforeSave можно отменить сохранение данных в базу, для примера есть несколько таблиц у которых есть поле ДатаВремя перед сохранением этого поля мы преобразуем с формата dd.mm.yyyy в формат базы yyyy-mm-dd например, тут же нам нужно проверить допустимое значение, и если данные не корректные то возвращаем фальш и данные не будут внесены в базу, хотя такую проверку лучше реализовывать через rules(), но может быть разные случаи, может быть вариант что ошибки нету но данные не нужно вносить в базу, все зависит от ситуации. А метод afterSave не будет выполняться если возникла ошибка или сохрание данных было отменено.

П.С. Я относительно новичок, если я что то не правильно понимаю поправьте меня специ )

Порой не столько важна возможность отменить сохранение в beforeSave(), сколько бывает необходимо каким-либо образом изменить данные перед записью их в базу или что-нибудь куда-нибудь записать (но последнее чаще делается в afterSave()).