Events στο Yii

Για να δούμε τι ακριβώς είναι τα events στο Yii.

Tι είναι ένα event? Το γεγονός πως βρισκόμαστε μέσα σε ένα Component (οτιδήποτε γίνεται extent από το CComponent και οι παλιότεροι θα ξέρετε πως είναι πάρα πολλές κλάσεις!) και θέλουμε να εκφράσουμε πως σε ορισμένα σημεία του κώδικα γίνεται κάτι!

Δηλαδή έχουμε γράψει μια μέθοδο πχ. runForestRun()

Άρα αντί απλά να εκτελέσουμε τον κώδικα εντός της μεθόδου θέλουμε επιπλέον να εκφράσουμε πως ο forest έτρεξε. Να πούμε δηλαδή πως έγινε αυτό το event. Γιατί? Επειδή μπορεί άλλοι να ενδιαφέρονται για αυτό το γεγονός (event) και να αντιδράσουν, να κάνουν τις δικές τους ενέργειες.

Άρα θέλουμε το εξής:




<?

public function runForestRun(){

    //... arbitrary code before raising the event

    $myComponent->onForestRan(new CEvent($this));

    //... maybe some code over here after raising the event

}



Καταρχήν το




new CEvent($this)



είναι απλώς το βασικό αντικείμενο event του Yii.

Αυτό μπορεί κάποιος να το κάνει extend φυσικά αν θέλει επιπλέον δυνατότητες.

Για παράδειγμα μέσα στο CΑctiveRecord θα βρείτε το αντικείμενο CModelEvent.

Αλλά η βασική παράμετρος είναι κάπως έτσι.

Ναι όμως θα μου πείτε πως το component μου δεν έχει καμία μέθοδο onForestRan.

E, Θα την δηλώσουμε λοιπόν μέσα στο component κάπως έτσι:




public function onForestRan($event){

    $this->raiseEvent('onForestRan', $event);

}



Τυπικά εδώ απλά καλούμε το raiseEvent αλλά σίγουρα κάποιος μπορεί να προσθέσει επιπλέον κώδικα αν επιθυμεί κάτι extra. Η βασική σύμβαση είναι πως ένα event ορίζεται γράφοντας στην αρχή τη λέξη on και μετά με first-capital το όνομα του event.

Ωραία άρα εκτελέσαμε την παραπάνω γραμμή κώδικα για να φωνάξουμε οτι ο forest έτρεξε. Ποιοι όμως θα το ακούσουν αυτό? Ο Η/Υ δεν μπορεί να μαντέψει από μόνος του πρέπει να του έχουμε πει ποιοι είναι οι ενδιαφερόμενοι! Δηλαδή ποιοι θα είναι οι handlers.

Άρα νωρίτερα πριν το raise του event θα πρέπει να έχουμε εκτελέσει κάτι τέτοιο:




$myComponent->onForestRan = array(new SomeOtherClass, 'eventHandler1');



ή αυτό




$myComponent-> onForestRan = function() {};



ή γενικώς οποιαδήποτε callback συνάρτηση ορίζεται στην php: http://php.net/manual/en/language.pseudo-types.php

Εκτελούμε την παραπάνω γραμμή για κάθε ενδιαφερόμενο!

Έτσι θα μπορούσαμε να πούμε πως έχουμε μια λίστα από συναρτήσεις ή μεθόδους (στατικές ή μη) που θα εκτελεστούν όταν γίνει raise το event.

Σημειώστε πως όπως τόνισα παραπάνω όταν μια κλάσση φωνάζει ότι έγινε ένα event (ότι έτρεξε ο Forest) τότε το σωστό είναι τα event handlers (οι ενδιαφερόμενοι) να είναι άλλες οντότητες που τυχαίνει να ενδιαφέρονται σε αυτό το γεγονός και θέλουν να αντιδράσουν. Το να ορίσουμε να γίνει μια μέθοδος εντός της ίδιας κλάσσης είναι εφικτό αλλά χωρίς σπουδαίο νόημα.

Αν καταλάβαμε τι γίνεται με τα events να τα συνοψίσουμε στα εξής τρία βήματα:

  1. Ορίζουμε το event που θέλουμε ως μια μέθοδο μέσα στην class με το πρόθεμα on και τυπικά μέσα σε αυτήν εκτελείται το raise event.

  2. Ορίζουμε όλες τις callback συναρτήσεις (τους ενδιαφερόμενους) οι οποίες θα κληθούν με το raise του event και τελειώσαμε με την προετοιμασία.

  3. Εισάγουμε την εντολή $myComponent->onForestRan() σε όλα σημεία του κώδικα θεωρούμε πως χρειάζεται ώστε να γίνει raise το event στο runtime.

Διορθώστε με σε οτιδήποτε χρειαστεί ή δεν είναι απόλυτα κατανοητό :)

References:

http://www.yiiframework.com/doc/guide/1.1/en/basics.component#component-event

http://www.yiiframework.com/wiki/44/behaviors-events

http://www.yiiframework.com/wiki/255/using-events-with-caction-classes