Yii-додатки складаються з компонентів-обʼєктів, створених згідно специфікацій. Компонент (component) — це екземпляр класу CComponent або похідного від нього. Використання компоненту в основному включає доступ до його властивостей, а також виклик і обробку його подій. Базовий клас CComponent встановлює те, як визначаються властивості та події.
Властивість компонента схожа на публічну змінну-член класу (public member variable). Ми можемо читати або встановлювати його значення. Наприклад:
$width=$component->textWidth; // отримуємо значення властивості textWidth
$component->enableCaching=true; // встановлюємо значення властивості enableCaching
Існують два різні способи визначення властивостей компонента. Перший шлях це просто оголосити публічну змінну у класі компонента, наприклад:
class Document extends CComponent
{
public $textWidth;
}
Інший спосіб полягає у використанні методів отримання (getter) та встановлення (setter). Цей спосіб більш гнучкий, оскільки додатково до звичайних властивостей ви можете оголосити властивість тільки для читання або тільки для запису.
class Document extends CComponent
{
private $_textWidth;
protected $_completed=false;
public function getTextWidth()
{
return $this->_textWidth;
}
public function setTextWidth($value)
{
$this->_textWidth=$value;
}
public function getTextHeight()
{
// розраховує та повертає висоту тексту
}
public function setCompleted($value)
{
$this->_completed=$value;
}
}
Компонент вище, можна використовувати наступним чином:
$document=new Document();
// ми можемо писати та читати textWidth
$document->textWidth=100;
echo $document->textWidth;
// ми можемо тільки читати textHeight
echo $document->textHeight;
// ми можемо тільки писати completed
$document->completed=true;
При спробі прочитати властивість компонента і властивість не визначена,
як відкритий член класу (public class member),
Yii намагатиметься використовувати метод отримання (getter), наприклад
для textWidth
метод отримання буде getTextWidth
.
Те ж саме відбувається при спробі запису властивості, яка не визначена як відкритий член класу.
Якщо існує метод-отримувач (getter), але відсутній метод-встановлювач (setter) — властивість компонента стає доступною тільки для читання та генерує виключення при спробі запису в неї. Якщо ж це навпаки, властивість доступна тільки для запису.
Використання методів отримання та встановлення для визначення властивості має користь у тому, що додаткові дії (такі як перевірка, виклик події) можуть бути виконані при читанні і запису властивості.
>Note|Примітка: Є невелика різниця у визначенні властивості через методи та через просте оголошення змінної. У першому випадку імʼя властивості нечутливе до регістру, у другому — чутливо.
Події компонента — це спеціальні властивості, у якості значень яких виступають методи (обробник подій). Прикріплення методу до події приведе до того, що метод буде викликаний автоматично при виникненні події. Тому поведінка компонента може бути задана зовсім відмінною від тієї, що закладається при розробці.
Подія компоненту задається шляхом створення методу з іменем, що починаються на on
.
Подібно іменам властивостей, заданих через методи читання й запису, імена подій
не чутливі до регістру. Наступний код задає подію onClicked
:
public function onClicked($event)
{
$this->raiseEvent('onClicked', $event);
}
де $event
— це екземпляр класу CEvent або похідного від нього,
що представляє параметр події. До події можна підключити обробник, як показано нижче:
$component->onClicked=$callback;
де $callback
— це коректний callback-виклик PHP (див. PHP-функцію call_user_func
).
Це може бути або глобальна функція, або метод класу.
В останньому випадку виклику повинен передаватись масив: array($object,'methodName')
.
Обробник події повинен бути визначений наступним чином:
function methodName($event)
{
…
}
де $event
— це параметр, що описує подію (відбувається із виклику raiseEvent()
).
Параметр $event
— це екземпляр класу CEvent або його похідного.
Як мінімум, він містить інформацію про те, хто викликав подію.
Обробник події може бути анонімною функцією, яка потребує наявності версії PHP 5.3+. Наприклад:
$component->onClicked=function($event) {
…
}
Якщо тепер викликати метод onClicked()
, подію onClicked
буде викликано
(всередині onClicked()
), і прикріплений обробник події буде запущений автоматично.
До події може бути прикріплено кілька обробників.
При виникненні події обробники будуть викликані в тому порядку,
у якому вони були прикріплені до події.
Якщо всередині обробника необхідно запобігти виклику наступних обробників,
необхідно встановити $event->handled в true
.
Для компонента була додана підтримка шаблону проектування домішок (mixin), що дозволяє прикріпити до нього одну або кілька поведінок. Поведінка — це обʼєкт, чиї методи «успадковуються» компонентом, до якого прикріплені. Під «успадкуванням» мається на увазі нарощування функціоналу, а не успадкування у класичному розумінні. До компонента можна прикріпити кілька поведінок і, таким чином, одержати множинне спадкування.
Поведінка класів повинна реалізовувати інтерфейс IBehavior. Більшість поведінок можуть бути створені шляхом розширення базового класу CBehavior. У випадку, якщо поведінку необхідно прикріпити до моделі, її можна створити на основі класу CModelBehavior або класу CActiveRecordBehavior, який реалізує додаткові, специфічні для моделі, можливості.
Щоб скористатися поведінкою, її необхідно прикріпити до компонента шляхом виклику методу attach(). Далі ми викликаємо метод поведінки через компонент:
// $name унікально ідентифікує поведінки в компоненті
$component->attachBehavior($name,$behavior);
// test() є методом $behavior
$component->test();
До прикріпленої поведінки можна звертатися, як до звичайної властивості компоненту.
Наприклад, якщо поведінка з іменем tree
прикріплена до компонента, ми можемо одержати
посилання на цей обʼєкт поведінки таким чином:
$behavior=$component->tree;
// еквівалентно виразу:
// $behavior=$component->asa('tree');
Поведінку можна тимчасово деактивувати таким чином, щоб її методи були недоступні через компонент. Наприклад:
$component->disableBehavior($name);
// вираз нижче приведе до виклику виключення
$component->test();
$component->enableBehavior($name);
// тут все буде працювати нормально
$component->test();
У випадку, коли дві поведінки, прикріплені до одного компоненту, мають методи з однаковими іменами, перевагу буде мати метод поведінки, яка була прикріплена першою.
Використання поведінок разом із подіями дає додаткові можливості. Поведінка, прикріплена до компонента, може привласнювати деякі свої методи подіям компоненту. В цьому випадку, поведінка отримує можливість стежити або змінювати нормальний хід виконання компоненту.
Властивості поведінки також можуть бути доступні із компонента, до якого вона привʼязана.
Властивості містять у собі як відкриті, так і визначені через геттери та/або сеттери поведінки.
Наприклад, поведінка має властивість із іменем xyz
і привʼязана до компонента
$a
. Тоді ми можемо використовувати вираз $a->xyz
для доступу до властивості.