Přejít k navigační liště

Zdroják » PHP » Generovanie kódu s Yii framework

Generovanie kódu s Yii framework

Články PHP, Různé

Yii, free open-source framework, je dostupný verejnosti približne od roku 2008. Jeho autor sa podieľal na vývoji frameworku Prado. Yii prichádza so silou, šikovnosťou a množstvom funkcií, ktoré urýchľujú vývoj webových projektov. Jednou z tých najšikovnejších, najviac uľahčujúcich prácu, je generovanie kódu — o ňom si dnes povieme.

Úvod

Ako Yii mieša karty PHP frameworkov sa už na Zdrojáku písalo. Poďme sa pozrieť ako Yii automaticky generuje kód.

Generovanie kódu

Tak ako sme začali využívať objektovo orientované programovanie po procedurálnom, a tak ako sme prešli ku MVC, tak si zaiste zvykneme na generovanie kódu a nebudeme chcieť už nič iné. Generovanie kódu patrí dnes k jedným z najdôležitejších (tzv. core) funkcií frameworkov. Tie, ktoré ho majú sa i vďaka nemu umiestňujú na vyšších priečkach v hodnoteniach. Yii framework medzi ne patrí, generovanie kódu má zvládnuté na jedničku, ľahko si naň zvyknúť.

Na začiatku cyklu projektu existuje len tabuľka v databáze, neskôr k nej vytvárame istú abstrakciu — model, vďaka ktorému môžeme k tabuľke vhodne pristupovať a meniť jej záznamy. Potom vytvárame v Controlleri konkrétne akcie (CRUD) slúžiace na manipuláciu s jej záznamami. Create Read Update Delete je súbor akcií, ktoré vykonávame takmer v každom projekte a takmer pri každom modeli. Nech sa jedná o akékoľvek entity v databáze, tieto operácie s nimi potrebujeme vykonávať vždy, a mechanické písanie kódu nás nikam neposúva, práve naopak.

Neustále písanie tej istej funkcionality pravdepodobne niekomu liezlo poriadne na nervy, a tak sa rozhodol tieto časti zautomatizovať — generovať ich.

Yii generuje kód za nás a spomínané kroky nie je nutné vykonávať, pretože obsahuje vstavané funkcie pre generovanie modulov, modelov a kompletných CRUDov vrátane controllerov, ktoré spolupracujú s modelom založeným na ActiveRecord a umožňujú nám vykonávať štyri spomínané operácie. Samozrejmosťou je že, môžu byť naviazané na modul. Yii framework teda dodržuje architektúru MVC v každom smere, a to i pri generovaní kódu.

Yii ponúka generovanie kódu pomocou CLI ale i pomocou GUI — týmito dvoma sa budeme primárne zaoberať.

I. Príkazový riadok – CLI

CLI ponúka (ak nerátame help) 4 konzolové príkazy:

  • message pre správu prekladov
  • migrate pre manažovanie zmien v databáze
  • shell pre spustenie CLI ku aplikácií
  • webapp pre vygenerovanie základnej aplikácie
$ ./yiic help

Hint: Pri používaní na Windowse treba použiť yiic.bat

Všetky príkazy nájdeme v priečinku framework/cli/commands, konkrétne s názvami MessageCommand.php, MigrateCommand.php, ShellCommand.php a WebAppCommand.php, pričom pre ShellCommand.php sú zadefinované aj „podpríkazy“.

WebApp – prvotná aplikácia

Yii umožňuje vygenerovať jednoduchú aplikáciu, ktorá môže byť základom pre kompletný projekt.

$ cd framework
$ ./yiic webapp ../aplikacia

Hint: Pre človeka menej skúseného s Yii odporúčam začať práve s webapp.

Po vygenerovaní aplikácie sa môžeme presunúť do adresára protected v našej aplikácií, kde je pre nás dostupné CLI (súbor yiic), avšak už s konfiguráciou pre našu aplikáciu.

$ cd ../aplikacia/protected/

Dostupné sú stále 4 príkazy.

Shell

$ ./yiic shell ../index.php
$ help

Pričom ../index.php je náš index súbor projektu — z neho sa načíta konfigurácia.

Shell ponúka opäť niekoľko príkazov:

  • controller pre vygenerovanie controllera i s akciami, prípadne s reláciou k modulu
  • crud pre vygenerovanie CRUD akcií nad modelom (možnosť relácie k modulu)
  • form pre generovanie modelu pre formulár
  • model pre generovanie modelu s možnosťou zadať názov tabuľky v databáze (dajú sa vygenerovať i všetky naraz)
  • module pre vygenerovanie modulu pre aplikáciu i so základnou adresárovou štruktúrou

Po zadaní jedného z príkazov bez parametrov ( model resp. help model) sa nám zobrazí podrobný návod na použitie konkrétneho príkazu i s príkladmi.

>> model

Z príkladov je jasné, že model je možné vygenerovať niekoľkými spôsobmi. Podobne sú na tom i ostatné príkazy.

Migrate a Message

Tieto príkazy až tak ku generovaniu kódu nepatria, preto sa nimi budeme zaoberať neskôr.

Vytvorenie vlastného konzolového príkazu

Základom všetkých konzolových príkazov je CConsoleCommand. Používa sa ako pri ShellCommand tak i pri WebAppCommand a ostatných príkazoch. CConsoleCommand je v podstate Controller, ktorý sa stará o spracovanie parametrov a beh samotného príkazu. Tak ako aj Controller, má akcie (metódy s prefixom action, ktoré je možné volať s tým, že predvolená akcia je index, no je možné ju zmeniť).

Hint: Netreba zabudnúť, že konzolová aplikácia má tiež svoj config:  protected/config/console.php

Aby sme mohli využívať vlastný konzolový príkaz, ktorý bude pre nás dostupný, takisto ako CRUD, či controller, je nutné vytvoriť si v priečinku protected/commands/shell súbor s triedou, ktorá rozširuje  CConsoleCommand:

$ cd protected/commands/shell
$ vim HelloWorldCommand.php

Príklad:

<?php
class HelloWorldCommand extends CConsoleCommand {
    public function actionIndex() {
        echo 'Hello world!';
    }
}
?>

Spustenie (zo shellu):

>> helloworld

V prípade, že by sme chceli vytvorený skript spúšťať napríklad pomocou CRONu, stačí opäť spustiť yiic a ako argument zadať názov konzolového príkazu.

$ ./yiic helloworld

II. Gii webové rozhranie – GUI

Gii generátor kódu zapneme tak, že tento modul povolíme v hlavnom konfiguračnom súbore protected/config/main.php a nastavíme heslo pre prístup k nemu.

<?php

'modules'=>array(
    'gii'=>array(
        'class'=>'system.gii.GiiModule',
        'password'=>'1_My_3_Secure_5_Password_7',
        'ipFilters'=>array('127.0.0.1','::1'),
//      'generatorPaths' => array(
//          'application.gii', // znamená "protected/gii" (default)
//      ),
//      'newDirMode' => 0755, // default 0777
//      'newFileMode' => 0644, // default 0666
    ),
),

?>

Existuje ešte pár možností ako Gii nastaviť (viď príklad vyššie).

  • generatorPaths určuje cesty, kde máme umiestnené vlastné kódy/šablóny pre generovanie
  • ipFilters povoľuje IP adresy odkiaľ je možné Gii spustiť

Hint: Kvôli bezpečnosti je dobré ponechať prístupné Gii len z lokálnej IP adresy.

Po úspešnom prihlásení máme na výber, podobne ako pri CLI, 5 možností (controller, crud, form, model a modul).

Vygenerovaný kód

Jednotlivé generátory vytvárajú rôzne súbory a priečinky. Príkazy controller a crud pridávajú súbory do protected/controllers a šablóny do protected/views, model a form zase do protected/models, a module vygeneruje podobnú štruktúru aká sa nachádza v protected  do protected/modules. Konkrétne názvy súborov samozrejme závisia od názvu modelov.

Rozšírenie a prispôsobenie Gii

Predstavme si, že sme sa rozhodli upraviť si generátor pre model tak, aby negeneroval v kóde žiadne komentáre, aby v ňom nebola funkcia relations() ani search() a aby zátvorky funkcií boli na konci riadku (tam kde je názov funkcie a nie na novom), prípadne chceme pridať nejaké anotácie. Skopírujeme si teda súbor framework/gii/generators/model/templates/default/model.php do protected/gii/model/templates/custom/model.php, vymažeme nepotrebné časti kódu a získame jednoduchý custom model:

Nové téma

Nevíte si rady? Něco vám nefunguje? Zeptejte se
ostatních čtenářů na našem fóru!
      

<?php echo "<?phpn"; ?>
/**
 * @author Vladimír Kriška
 * @version 1.2.0
 * @since Version 1.0.1
 */
class <?php echo $modelClass; ?> extends <?php echo $this->baseClass; ?> {

    public static function model($className=__CLASS__) {
        return parent::model($className);
    }

    public function tableName() {
        return '<?php echo $tableName; ?>';
    }

    public function rules() {
        return array(

<?php foreach($rules as $rule): ?>
            <?php echo $rule.",n"; ?>
<?php endforeach; ?>
        );
    }

    public function attributeLabels() {
        return array(
<?php foreach($labels as $name=>$label): ?>
            <?php echo "'$name' => '$label',n"; ?>

<?php endforeach; ?>
        );
    }

}

Akonáhle je úprava šablóny na generovanie hotová, je možné ju používať, pretože Gii ju deteguje a zobrazí sa vo výbere ponúkaných šablón.

Podobným spôsobom môžeme upraviť akékoľvek časti generovaného kódu, napr. zmeniť spôsob generovania formulárov pre CRUD tak, aby boli v tabuľkách. Alebo do nich, v prípade viacjazyčnej aplikácie, rovno implementovať preklady.

Referencie

Komentáře

Subscribe
Upozornit na
guest
22 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
View all comments
mato

konecne poriadny clanok o Yii

LV

Yii ma bezesporu zajimavou koncepci a radu moc peknych vlastnosti. Ma ale vyznam jim v soucasnosti zabyvat, kdyz z komunity kolem prosakuji informace, ze bude na prelomu 2011/2012 kompletne prepsan bez zachovani zpetne kompatibility? Je vubec vhodne jej v takovem pripade nasazovat do produkcniho prostredi?

ujovlado

Určite má význam sa nim zaoberať. Pretože nebudeš predsa čakať, kým vydajú nové Yii … projekty treba robiť stále.

Žiadne hlasy z komunity nepresakujú – je to uvedené oficiálne na stránke.

Jednoducho keď vydajú nové Yii, budeš nové projekty robiť na novom.

Momentálne je zaručená podpora do konca 2012 a dovolím si tvrdiť, že bude ešte predĺžená, takže nie je sa čoho báť a určite by ma to neodrádzalo od nasadenia do produkčnej verzie.

VM

Nebyl by někde přehled zajímavých featur, aby člověk viděl, zda se mu to vůbec hodí?

ujovlado

prehlad fíčur + čo a ako sa robí si môžeš pozrieť napríklad tu:
http://www.yiiframework.com/doc/guide/

zároveť je to sprievodca Yii.

gawan

Zdravím,
ďakujem za článok. Mám otázku. Čo sa stane ak urobím toto:
1. vygenerujem model z tabuľky
2. potom model ručne upravím
3. potom dostanem požiadavku pridať nejaké nové stĺpce do tabuľky
4. potom znovu vygenerujem model

čo sa stane? prepíše mi moje úpravy, alebo je tak inteligentný, že dokáže pridať nové vlastnosti do vygenerovaného súboru?

ujovlado

Takúto situáciu bohužiaľ Yii nerieši. Generátor sa ťa ale spýta, či chceš už vygenerované časti prepísať…

Riešim to tak, že keď je už veľa úprav, tak tie upravené si odložim, pregenerujem a potom „zmergeujem“. Ak úprav veľa nebolo dám to všetko prepísať.

Hlavne sa snažím aby mi takáto situácia nenastala.

Michal

To snad nemyslite vazne :-) .
uz Doctrine 1 tohle mela vyresene – generovane tridy jsou jsou tzv. Base<ModelName> a Vam pouze pokud uz ji nemate vygeneruje prazdnou <ModelName>.

Pridavani atributu do modelu je prece bezna soucast vyvoje, jestli je v tom FW takovahle bota tak mi to nestoji ani za napsani URL do prohlizece

ujovlado

Asi sme sa nepochopili.

Pridanie atribútov vôbec nie je problém – model sa dá jednoducho pregenerovať. Avšak ak máš už vygenerovaný celý CRUD (Controller + všetky views) a v jednej z týchto častí niečo upravíš, potom pridáš atribút a následne chceš opäť všetko pregenerovať – samozrejme narazíš na konflikt.

Doctrine ti to automaticky „mergeuje“?

gawan

nie nemergeuje, prečítaj si čo písal ešte raz. Doctrine generuje BaseModel, do ktorého ty nikdy nezasahuješ, ale keď robíš nejaké úpravy tak ich robíš v potomkovi BaseModelu. takže kľudne môžeš pregenerovať BaseModel koľko krát chceš a tvoje modifikácie to nejako neovplyvní, lebo sú v potomkovi.

ujovlado

Čítal som to. Neviem, no, ja osobne to v Yii ako problém nevidím. Je to tak navrhnuté – tak to funguje.

Sú prípady kedy ti stači dopísať políčko do views, pretože Yii si info o nových stĺpcoch automaticky naťahuje z db a sú prípady, kedy potrebuješ urobiť toho viac. ;-) Yii mi uľahčuje prácu, lebo vie generovať všetko.

Ako je to v Doctrine? Vygeneruje len model alebo i controller a views?

Michal

Doctrine 1 generuje na prani i CRUD, ma celkem dost cli prikazu na generovani:

doctrine
:build Generate code based on your schema
:build-db Creates database for current model (doctrine:create-db)
:build-filters Creates filter form classes for the current model
:build-forms Creates form classes for the current model
:build-model Creates classes for the current model
:build-schema Creates a schema from an existing database
:build-sql Creates SQL for the current model
:clean-model-files Delete all generated model classes for models which no longer exist in your YAML schema (doctrine:clean)
:create-model-tables Drop and recreate tables for specified models.
:data-dump Dumps data to the fixtures directory
:data-load Loads YAML fixture data
:delete-model-files Delete all the related auto generated files for a given model name.
:dql Execute a DQL query and view the results
:drop-db Drops database for current model
:generate-admin Generates a Doctrine admin module
:generate-migration Generate migration class
:generate-migrations-db Generate migration classes from existing database connections
:generate-migrations-diff Generate migration classes by producing a diff between your old and new schema.
:generate-migrations-models Generate migration classes from an existing set of models
:generate-module Generates a Doctrine module
:generate-module-for-route Generates a Doctrine module for a route definition
:insert-sql Inserts SQL for current model
:migrate Migrates database to current/specified version

Ja pouzivam vlastne jenom doctrine:build –all –and-load coz mi podle aktualniho databazoveho schema.yml pregeneruje BaseModel tridy (ze kterych jak kolega vyse upresnil dedim moje custom Model tridy), formulare modelu a dalsi veci.
Kompletni CRUD vygenerujes pomoci generate-module (http://www.symfony-project.org/jobeet/1_4/Doctrine/en/03#chapter_03_see_it_in_action_in_the_browser)
(v symfony by to melo byt naprosto stejny)

Sve custom formulare delam nad modely zase podedene z vygenerovanych, takze kazdym pregenerovanim ziskam funkcnost i do nich, pouze pokud jsou sepsane tak, aby byly zamerne omezeny na konkretni pole, tak tam ty nove musim samozrejme pridat.

Doctrine jako ORM by se nemelo zabejvat generovanim cehokoli jinyho nez jsou veci ohledne DB a Modelu, coz je taky zakladni myslenka nove Doctrine 2.
Ta stara 1ka je celkem prasarna, ale funguje 100% a ma par moc peknych featur pro pristup k datum :-).

Kolemjdoucí

To snad nemyslíš vážně :-) To je tak těžké si Base třídu vygenerovat a změny dělat taky ve vlastní třídě?

drla

Nie , pokial ja viem ten generator je „hlupy“ a vzdy ked cokolvek generujes ti to natvrdo prepise… Cize da sa vyuzit len na prvotne generovanie modelu , contolllerov a views…

ujovlado

1. Aj si si to vyskúšal? Či len píšeš, lebo ti niekto povedal, že je hlúpy?
2. V čom teda generuješ kód?

Generátor sa ťa spýta na každý jeden súbor, ktorý už existuje – že či ho chceš prepísať (píšem to i vyššie v diskusii).

Ďalšia vec je, že ak často potrebuješ pridávať stĺpce do databázy a následne pregenerovávať kód asi niečo nebude v poriadku s návrhom, hmm?

drla

Keby som to neskusal tak neodpisujem ;) dal som do uvodzoviek ze je hlupy, co neznamena ze je zly a tym padom plati ze sa da vyuzivat len na prvotne generovanie modelu a vsetko co si napisal je pravda…

inteligentny by mi pripadal vtedy keby pri re-generovani modelu vedel odlisit povodnu sablonu podla ktorej generuje od customizovanych metod a tym padom by ich neprepisal.

Nepridavam stlpce do tabulky casto ale sem tam to potrebujes , ale zas to nie je ziadna katastrofa a jednoducho si pridam nejake validacne pravidlo popripade label rucne a je to vyriesene…

ujovlado

Ak generuješ cez Gii, je tam na to veľmí jednoduchý diff – bohužiaľ len na zobrazenie zmien …

Srigi

Cau Drla, budes este o Yii blogovat?

drla

cau, ak bude mat den 48 hodin tak budem pokracovat :))) bohuzial je to o volnom case a ten ani nahodou nemam… aj na zajtra.sk serial zakapal po 4 castiach, tiez asi nema cas ;) mozno na buduci mesiac nieco pripravim , ale ako si mi to komentoval bolo by asi vhodnejsie to nasmerovat inym smerom ;)

vvoody

Zislo by sa dopisat, ze ku gii sa v novo vytvorenej aplikacii pristupuje cez „index.php?r=gii“. Tamten zapis „/gii“ funguje asi az po uprave url manazera, ak som sa dobre docital.
http://www.yiiframework.com/doc/guide/1.1/en/topics.gii

ujovlado

Áno, máš pravdu!

Ďakujem za upozornenie. ;-)

tom

Proc je to napsane ve slovenstine, nevsim sem si ze v adrese je root.sk
To pak ctenare odradi cist .

Enum a statická analýza kódu

Mám jednu univerzální radu pro začínající programátorty. V učení sice neexistují rychlé zkratky, ovšem tuhle radu můžete snadno začít používat a zrychlit tak tempo učení. Tou tajemnou ingrediencí je statická analýza kódu. Ukážeme si to na příkladu enum.

Pocta C64

Za prvopočátek své programátorské kariéry vděčím počítači Commodore 64. Tehdy jsem genialitu návrhu nemohl docenit. Dnes dokážu lehce nahlédnout pod pokličku. Chtěl bych se o to s vámi podělit a vzdát mu hold.