Hur man programmerar med Yii2 Timestamp Behavior

Vad du ska skapa

Om du frågar, "Vad är Yii?" kolla in min tidigare handledning: Introduktion till Yii Framework, som granskar fördelarna med Yii och innehåller en översikt över vad som är nytt i Yii 2.0, släppt i oktober 2014.

I denna programmering med Yii2-serien guidar jag läsare som använder den nyuppgraderade Yii2 Framework for PHP. I denna handledning undersöker vi Timestamp Behaviors, vilket minskar mängden kod du behöver skriva med varje ny modell för den gemensamma funktionen att skapa tidsstämplar för inlägg och uppdateringar. Vi dyker också in i källkoden Yii2 och undersöker hur ett beteende implementeras.

För exemplen i den här handledningen fortsätter vi att föreställa oss att vi bygger ett ramverk för att publicera enkla statusuppdateringar, t.ex. vår egen mini-Twitter.

Bara en påminnelse, jag deltar i kommentera trådarna nedan. Jag är särskilt intresserad om du har olika tillvägagångssätt, ytterligare idéer, eller vill föreslå ämnen för framtida handledning.

Vad är ett beteende?

Yii2 Behavior är i huvudsak mixins. Wikipedia beskriver mixins som "en klass som innehåller en kombination av metoder från andra klasser. Hur en sådan kombination görs beror på språket, men det är inte av arv."

Yii beskriver dem så här:

Att anbringa ett beteende på en komponent "injicerar" beteendets metoder och egenskaper i komponenten, vilket gör de metoderna och egenskaperna tillgängliga som om de definierades i komponentklassen själv.

Yii2 erbjuder flera inbyggda beteenden, varav de flesta dokumenteras, inklusive sluggable, skyldig och tidstämpel. Beteenden är ett enkelt sätt att återanvända gemensam kod på många av dina datamodeller utan att behöva upprepa koden på många ställen. Injicera ett beteende i en modell kan ofta göras med bara två rader av kod. När antalet modeller i din ansökan ökar blir beteenden mer och mer användbara.

Vad är Timestamp Beteende?

Timestamp Behavior gör det enkelt för oss att genomföra den ofta nödvändiga uppgiften att tilldela aktuellt datum och tid till inlägg och uppdateringar i en ActiveRecord-modell, automatiskt inställning av egenskaperna för skapad vid och updated_at.

Tidigare i denna serie genomförde vi timestämpelbeteende manuellt. När statusmodeller postades av användaren som skickade in ett formulär, tilldelade vi nuvarande Unix tidsstämpel till båda fälten:

 public function actionCreate () $ model = ny status (); om ($ modell-> ladda (Yii :: $ app-> request-> post ())) $ model-> created_at = time (); $ model-> updated_at = time (); om ($ model-> save ()) return $ this-> omdirigera (['view', 'id' => $ model-> id]);  annars var_dump ($ model-> getErrors ()); dö();  

Genomförandet av Timestamp-beteendet kommer att göra det automatiskt för oss och kan enkelt läggas till i alla ActiveRecord-modeller i ett webbprogram.

Genomföra Timestamp Behavior i Status Model

Nästan varje modell jag skapar i Yii har a skapad vid och updated_at fält. Det är bra träning. Således är Timestamp-beteendet användbart i nästan alla modeller.

Lägga till timestämpelns beteende i statusmodellen

I modeller / Status.php vi lägger till TimestampBehavior efter Sluggable och Blameable:

 public function behaviors () return [['class' => SluggableBehavior :: className (), 'attribute' => 'meddelande', 'immutable' => true, 'secureUnique' => true,], => BlameableBehavior :: className (), 'createdByAttribute' => 'created_by', 'updatedByAttribute' => 'uppdaterad_by',], 'timestamp' => ['class' => 'yii \ behaviors \ TimestampBehavior', 'attribut '=> [ActiveRecord :: EVENT_BEFORE_INSERT => [' created_at ',' updated_at '], ActiveRecord :: EVENT_BEFORE_UPDATE => [' updated_at '],],],]; 

Vi måste också inkludera ActiveRecord-klassen längst upp i vår modell (jag glömmer alltid den här delen):

Sedan tar vi bort den nödvändiga regeln för skapad vid och updated_at i modellreglerna:

 allmänna funktionsregler () return [[['message', 'created_at', 'updated_at'], 'required'], [['meddelande'], 'string'], [['behörigheter', 'created_at' 'updated_at', 'created_by'], 'integer']];  

Så här:

 public function rules () return [[['' message '],' required '], [[' message '],' string '], [[' behörigheter ',' created_at ',' updated_at ',' created_by '] , 'heltal']];  

Detta gör det möjligt för valideringen att lyckas och fortsätta till beteenden.

Vi måste också ta bort StatusControllerens skapad vid och updated_at uppdrag i skapandet:

 public function actionCreate () $ model = ny status (); om $ model-> save ()) return $ this-> omdirigera (['visa', 'id' => $ modell-> id]);  annars var_dump ($ model-> getErrors ()); dö();  returnera $ this-> render ('create', ['model' => $ modell,]);  

När alla dessa ändringar är klara, kan vi skriva en ny statuspost:

Och den resulterande vyn visar skapad vid och updated_at inställningar som gjorts av Timestamp-beteendet.

Touch-metoden

Timestämpelbeteendet ger också en metod som heter Rör() som tillåter dig att tilldela den aktuella tidstämpeln till det angivna attributet och spara dem i databasen.

$ Modell-> touch ( 'updated_at');

Om du till exempel har ett bakgrundscronjobb som gör en del bearbetning på status tabellen kan du ha en last_processed_at tidsstämpel som du bifogar beteendet till. När cron-jobbet körs skulle du röra det där fältet:

$ Modell-> touch ( 'last_processed_at');

Kodkoden för tidsstämpelbeteende

Eftersom Yii2 nu stöder PSR-4-namngivningskonventionerna är det lättare att dyka direkt in i ramkoden för att se hur det fungerar. Låt oss ta en titt på TimestampBehavior kod för att förstå hur den implementeras.

Koden är länkad till GitHub från dokumentationssidan:

klass TimestampBehavior utökar AttributeBehavior / ** * @var sträng attributet som kommer att få tidsstämplingsvärde * Ställ in den här egenskapen till falsk om du inte vill spela in skapandetiden. * / public $ createdAtAttribute = 'created_at'; / ** * @var sträng det attribut som kommer att få tidstämplingsvärde. * Ställ den här egenskapen på fel om du inte vill spela in uppdateringstiden. * / public $ updatedAtAttribute = 'updated_at'; / ** * @var callable | Uttryck Det uttryck som ska användas för att generera tidsstämpeln. * Detta kan antingen vara en anonym funktion som returnerar tidsstämpelvärdet, * eller ett [[Expression]] -objekt som representerar ett DB-uttryck (t ex "New Expression (" NU () ")"). * Om den inte är inställd, kommer den att använda värdet av "time ()" för att ställa in attributen. * / offentligt $ värde; / ** * @inheritdoc * / public function init () förälder :: init (); om (tomt ($ this-> attribut)) $ this-> attributes = [BaseActiveRecord :: EVENT_BEFORE_INSERT => [$ this-> createdAtAttribute, $ this-> updatedAtAttribute], BaseActiveRecord :: EVENT_BEFORE_UPDATE => $ this-> updatedAtAttribute ,];  / ** * @inheritdoc * / skyddad funktion getValue ($ händelse) om ($ this-> value instanceof Expression) return $ this-> value;  annars returnera $ this-> value! == null? call_user_func ($ this-> värde, $ händelse): tid ();  / ** * Uppdaterar en tidsstämpelattribut till den aktuella tidsstämpeln. * * "php * $ model-> touch ('lastVisit'); *" * @param string $ ange namnet på attributet som ska uppdateras. * / public function touch ($ attribut) $ this-> owner-> updateAttributes (array_fill_keys (array) $ attribut, $ this-> getValue (null))); 

Standardattributen definieras här, och de kan anpassas i våra modeller:

 public $ createdAtAttribute = 'created_at'; public $ updatedAtAttribute = 'updated_at';

Vid initiering definierar beteendet vilka händelser som utlöser tidsstämpeluppdateringar för de angivna attributen:

allmän funktion init () förälder :: init (); om (tomt ($ this-> attribut)) $ this-> attributes = [BaseActiveRecord :: EVENT_BEFORE_INSERT => [$ this-> createdAtAttribute, $ this-> updatedAtAttribute], BaseActiveRecord :: EVENT_BEFORE_UPDATE => $ this-> updatedAtAttribute ,]; 

Du kan läsa mer om Yii2 ActiveRecord Events här.

De getValue Metoden returnerar nuvarande tidsstämpel för attributet om det är odefinierat:

skyddad funktion getValue ($ event) om ($ this-> value instance of Expression) returnera $ this-> value;  annars returnera $ this-> value! == null? call_user_func ($ this-> värde, $ händelse): tid ();  

Som standard, TimestampBehavior kommer att fylla skapad vid och updated_at attribut med den aktuella tidstämpeln när det associerade objektet infogas. Det fyller updated_at attribut med tidstämpeln när objektet uppdateras. Om det inte finns någon anpassad funktion tilldelad, använder den PHP tid() funktion, som returnerar den aktuella Unix tidsstämpeln.

Det implementerar också Rör metod för de definierade attributen:

/ ** * Uppdaterar en tidsstämpelattribut till den aktuella tidsstämpeln. * * "php * $ model-> touch ('lastVisit'); *" * @param string $ ange namnet på attributet som ska uppdateras. * / public function touch ($ attribut) $ this-> owner-> updateAttributes (array_fill_keys (array) $ attribut, $ this-> getValue (null))); 

Förhoppningsvis ger detta dig en uppfattning om hur man implementerar ditt eget modellbeteende. Om du skapar något nytt, lägg till en länk till koden i kommentarerna så att andra kan kolla in det.

Vad kommer härnäst?

Jag hoppas att du har tyckt om att lära dig om Yii2 Timestamp-beteenden och utforska Yii2-källkoden.

Titta på kommande handledningar i min programmering med Yii2-serien när jag fortsätter att dyka in i olika aspekter av ramen. Du kanske också vill kolla in min Building Your Startup With PHP-serie, som använder Yii2s avancerade mall när jag bygger en verklig världsapplikation.

Jag välkomnar funktion och ämnesförfrågningar. Du kan skicka in dem i kommentarerna nedan eller maila mig på min Lookahead Consulting webbplats.

Om du vill veta när nästa Yii2 handledning kommer, följ mig @ reifman på Twitter eller kolla min instruktörssida. Min instruktörssida kommer att innehålla alla artiklar från denna serie så snart de publiceras. 

relaterade länkar

  • Den Yii2 Definitive Guide: Behavior
  • Yii2 Dokumentation: Timestamp Beteende
  • Yii2 Developer Exchange, min Yii2 resurs webbplats