Hoe te programmeren met Yii2 Tijdstempelgedrag

Wat je gaat creëren

Als je vraagt: "Wat is Yii?" bekijk mijn eerdere tutorial: Introductie tot het Yii Framework, die de voordelen van Yii bekijkt en een overzicht bevat van wat er nieuw is in Yii 2.0, uitgebracht in oktober 2014.

In deze serie Programming With Yii2 begeleid ik lezers in gebruik van het onlangs bijgewerkte Yii2 Framework voor PHP. In deze zelfstudie zullen we Timestamp-gedrag verkennen, waarmee u de hoeveelheid code die u met elk nieuw model moet schrijven, moet verminderen voor de algemene bewerking van het maken van tijdstempels voor invoegingen en updates. We duiken ook in de Yii2-broncode en onderzoeken hoe een gedrag wordt geïmplementeerd.

Voor de voorbeelden in deze zelfstudie blijven we ons voorstellen dat we een raamwerk bouwen voor het plaatsen van eenvoudige statusupdates, bijvoorbeeld onze eigen mini-Twitter.

Ter herinnering, ik neem wel deel aan de commentaarthreads hieronder. Ik ben vooral geïnteresseerd in verschillende benaderingen, aanvullende ideeën of onderwerpen voor toekomstige zelfstudies.

Wat is een gedrag?

Yii2 Gedragingen zijn in wezen mixins. Wikipedia beschrijft mixins als "een klasse die een combinatie van methoden uit andere klassen bevat." Hoe een dergelijke combinatie wordt gedaan, is afhankelijk van de taal, maar niet van overerving. "

Yii beschrijft ze op deze manier:

Door een gedrag aan een component toe te voegen, worden de methoden en eigenschappen van het gedrag in de component geïnjecteerd, waardoor die methoden en eigenschappen toegankelijk worden alsof ze in de componentklasse zelf zijn gedefinieerd.

Yii2 biedt verschillende ingebouwde gedragingen, waarvan de meeste we zullen documenteren, inclusief loosbaar, blameable en timestamp. Gedragingen zijn een gemakkelijke manier om veelgebruikte code in veel van uw datamodellen te hergebruiken zonder de code op veel plaatsen te hoeven herhalen. Het injecteren van een gedrag in een model kan vaak worden gedaan met slechts twee regels code. Naarmate het aantal modellen in uw toepassing toeneemt, worden gedragingen steeds nuttiger.

Wat is het gedrag van de tijdstempel?

Het tijdstempelgedrag maakt het ons gemakkelijk om de vaak noodzakelijke taak van het toewijzen van de huidige datum en tijd aan invoegingen en updates in een ActiveRecord-model, waarbij automatisch de eigenschappen voor gemaakt bij en updated_at.

Eerder in deze reeks hebben we tijdstempelgedrag handmatig geïmplementeerd. Telkens wanneer Status-modellen werden gepost door de gebruiker die een formulier invulde, hebben we het huidige Unix-tijdstempel aan beide velden toegewezen:

 public function actionCreate () $ model = nieuwe status (); if ($ model-> load (Yii :: $ app-> request-> post ())) $ model-> created_at = time (); $ model-> updated_at = time (); if ($ model-> save ()) return $ this-> redirect (['view', 'id' => $ model-> id]);  else var_dump ($ model-> getErrors ()); dood gaan();  

Het tijdstempelgedrag implementeren zal dit automatisch voor ons doen en kan eenvoudig worden toegevoegd aan alle ActiveRecord-modellen in een webapplicatie.

Het tijdstempelgedrag implementeren in het statusmodel

Bijna elk model dat ik maak in Yii heeft een gemaakt bij en updated_at veld. Het is een goede gewoonte. Het gedrag van de tijdstempel is dus nuttig in bijna elk model.

Het tijdstempelgedrag toevoegen aan het statusmodel

In modellen / status.php we voegen het toe TimestampBehavior na Sluggable en Blameable:

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

We moeten ook de ActiveRecord-klasse aan de bovenkant van ons model opnemen (ik vergeet dit onderdeel altijd):

Vervolgens verwijderen we de vereiste regel voor gemaakt bij en updated_at in de modelregels:

 public function rules () return [[['message', 'created_at', 'updated_at'], 'required'], [['message'], 'string'], [['permissions', 'created_at', 'updated_at', 'created_by'], 'integer']];  

Zoals dit:

 public function rules () return [['message'], 'required'], [['message'], 'string'], [['permissions', 'created_at', 'updated_at', 'created_by'] , 'integer']];  

Hierdoor kan de validatie slagen en doorgaan met het gedrag.

We moeten ook de StatusController's verwijderen gemaakt bij en updated_at toewijzingen in de actie create:

 public function actionCreate () $ model = nieuwe status (); if ($ model-> load (Yii :: $ app-> request-> post ())) if ($ model-> save ()) return $ this-> redirect (['view', 'id') => $ model-> id]);  else var_dump ($ model-> getErrors ()); dood gaan();  return $ this-> render ('create', ['model' => $ model,]);  

Zodra al deze wijzigingen zijn voltooid, kunnen we een nieuw Status-bericht schrijven:

En de resulterende weergave toont de gemaakt bij en updated_at instellingen gemaakt door het gedrag van de tijdstempel.

De Touch-methode

Het gedrag van de tijdstempel biedt ook een methode met de naam Raak () waarmee u de huidige tijdstempel kunt toewijzen aan het (de) opgegeven attribuut (en) en deze in de database kunt opslaan.

$ Model-> touch ( 'updated_at');

Als u bijvoorbeeld een cron-achtergrondtaak hebt die enige verwerking in de statustabel uitvoert, heeft u mogelijk een last_processed_at tijdstempel waaraan u het gedrag koppelt. Telkens wanneer de cron-taak wordt uitgevoerd, raakt u dat veld aan:

$ Model-> touch ( 'last_processed_at');

De broncode van het tijdstempelgedrag

Omdat Yii2 nu de naamgevingsconventies van de PSR-4 ondersteunt, is het gemakkelijker om rechtstreeks in de raamwerkcode te duiken om te zien hoe het werkt. Laten we eens kijken naar de TimestampBehavior code om te begrijpen hoe het is geïmplementeerd.

De code is gekoppeld aan GitHub van de documentatiepagina:

class TimestampBehavior breidt AttributeBehavior / ** * @var uit string het attribuut dat timestamp-waarde zal ontvangen * Stel deze eigenschap in op false als u de creatie-tijd niet wilt registreren. * / public $ createdAtAttribute = 'created_at'; / ** * @var teken het attribuut in dat de tijdstempelwaarde zal ontvangen. * Stel deze eigenschap in op false als u de update-tijd niet wilt registreren. * / public $ updatedAtAttribute = 'updated_at'; / ** * @var opvraagbaar | Uitdrukking De uitdrukking die zal worden gebruikt voor het genereren van het tijdstempel. * Dit kan een anonieme functie zijn die de tijdstempelwaarde retourneert, * of een [[Expression]] - object dat een DB-uitdrukking vertegenwoordigt (bijvoorbeeld 'nieuwe expressie (' NOW () ')'). * Indien niet ingesteld, gebruikt het de waarde van 'time ()' om de attributen in te stellen. * / public $ waarde; / ** * @inheritdoc * / openbare functie init () parent :: init (); if (empty ($ this-> attributes)) $ this-> attributes = [BaseActiveRecord :: EVENT_BEFORE_INSERT => [$ this-> createdAtAttribute, $ this-> updatedAtAttribute], BaseActiveRecord :: EVENT_BEFORE_UPDATE => $ this-> updatedAtAttribute ,];  / ** * @inheritdoc * / beschermde functie getValue ($ event) if ($ this-> value instanceof Expression) return $ this-> value;  else return $ this-> value! == null? call_user_func ($ this-> value, $ event): time ();  / ** * Werkt een tijdstemamptribuut bij aan de huidige tijdstempel. * * "php * $ model-> touch ('lastVisit'); *" * @param string $ attribuut de naam van het attribuut dat moet worden bijgewerkt. * / openbare functie touch ($ attribuut) $ this-> owner-> updateAttributes (array_fill_keys ((array) $ attribuut, $ this-> getValue (null))); 

De standaardkenmerken worden hier gedefinieerd en kunnen in onze modellen worden aangepast:

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

Bij initialisatie bepaalt het gedrag welke gebeurtenissen tijdstempampedities activeren voor de opgegeven kenmerken:

openbare functie init () parent :: init (); if (empty ($ this-> attributes)) $ this-> attributes = [BaseActiveRecord :: EVENT_BEFORE_INSERT => [$ this-> createdAtAttribute, $ this-> updatedAtAttribute], BaseActiveRecord :: EVENT_BEFORE_UPDATE => $ this-> updatedAtAttribute ,]; 

U kunt hier meer lezen over Yii2 ActiveRecord-evenementen.

De getValue methode retourneert de huidige tijdstempel voor het kenmerk als het niet is gedefinieerd:

beschermde functie getValue ($ event) if ($ this-> value instanceof Expression) return $ this-> value;  else return $ this-> value! == null? call_user_func ($ this-> value, $ event): time ();  

Standaard, TimestampBehavior zal de vullen gemaakt bij en updated_at attributen met de huidige tijdstempel wanneer het bijbehorende object wordt ingevoegd. Het vult de updated_at attribuut met de tijdstempel wanneer het object wordt bijgewerkt. Als er geen aangepaste functie is toegewezen, gebruikt deze de PHP tijd() functie, die het huidige Unix-tijdstempel retourneert.

Het implementeert ook de aanraken methode voor de gedefinieerde attributen:

/ ** * Werkt een tijdstempelkenmerk bij aan de huidige tijdstempel. * * "php * $ model-> touch ('lastVisit'); *" * @param string $ attribuut de naam van het attribuut dat moet worden bijgewerkt. * / openbare functie touch ($ attribuut) $ this-> owner-> updateAttributes (array_fill_keys ((array) $ attribuut, $ this-> getValue (null))); 

Hopelijk geeft dit u een idee van hoe u uw eigen modelgedrag kunt implementeren. Als je iets nieuws maakt, plaats dan een link naar de code in de comments, zodat anderen het kunnen bekijken.

Wat is het volgende?

Ik hoop dat je het leuk hebt gevonden om meer te weten te komen over het gedrag van de Yii2 Timestamp en de Yii2-broncode te onderzoeken.

Kijk uit naar komende tutorials in mijn Programming With Yii2-serie terwijl ik verder duik in verschillende aspecten van het framework. Je kunt ook mijn Building Your Startup With PHP-serie bekijken, die de geavanceerde sjabloon van Yii2 gebruikt terwijl ik een toepassing in de echte wereld samenstel.

Ik verwelkom aanvragen voor functies en onderwerpen. Je kunt ze plaatsen in de reacties hieronder of e-mail me op mijn Lookahead Consulting-website.

Als je wilt weten wanneer de volgende Yii2-handleiding aankomt, volg me dan @reifman op Twitter of bekijk mijn instructeurspagina. Op mijn instructeurspagina staan ​​alle artikelen uit deze serie zodra ze zijn gepubliceerd. 

Gerelateerde Links

  • De Yii2 definitieve gids: gedrag
  • Yii2-documentatie: tijdstempelgedrag
  • Yii2 Developer Exchange, mijn Yii2-bronsite