Jaké ORM rubrika: Programování: PHP

6 SpaceAngel
položil/-a 5.5.2016

Ahoj,

jaký byste zvolili ORM pro PHP a proč?

Řeším nový projekt, a kromě Doctrine nic neznám, tak chci vědět, jestli jsou i alternativy.

PHP 5.5, framework vlastní, databáze MySQL (kdyby to ale umělo víc DB, zlobit se nebudu), data charakteru finančních.

Díky:)

Komentáře

  • roman.hocke : Nejdřív by bylo zajímavé znát odpověď právě na to "proč". Proč potřebuješ ORM? Co od něj očekáváš? Jaké problémy s obyčejným SQL máš, že se sháníš po ORM? 6.5.2016
  • SpaceAngel : No, na to nedokazu uplne presne odpovedet:-) Doted jsem byl zastancem cisteho sql. Ale nejak si myslim, ze ORM by urychlilo vyvoj aplikace - mozna naivne, mozna ne. Nemusel bych slozite psat spoustu dotazu, a v podstate orm by to poskladalo/vyresilo za me. Mozna se mylim. 6.5.2016
  • Kit : ORM velmi urychlí vývoj aplikace. Tedy na začátku. Ke konci už je spíše brzdou, protože se některé z jeho vlastností se musí obcházet, aby se docílilo požadované funkčnosti a výkonu. 6.5.2016
  • harrison314 : @Kit: to, ze ORM znizuej vykon je kazdemu jasne, to ci to bude na konci bordel zelazi od ORM kniznice a programtora, no na 90% od programtora. 6.5.2016
  • podhy : Na běžnej CRUD (což být stejně tak 80% všech aplikací) je ORM v pohodě - tam je jedno jestli je projekt na začátku nebo na konci. Na složitější věci stejně člověk musí sáhnout po SQL. 6.5.2016
  • harrison314 : @podly: to tiez zelazi na ORM, take Active record (napr orm pouzite v Yii) take veci nezvlada a je naozaj dobre len na CRUD, ale full feature ORM (ako Entity Framework, alebo Hibernate), v pohode zvlda aj velmi zlozite veci bez SQL-ka. 6.5.2016
  • Kit : @podhy: Co jsem si stačil všimnout, tak běžné ORM nezvládají ani CRUD - obvykle jim chybí položka "update". 6.5.2016
  • xxar3s : Neviem ako bezne orm ale v EF ked priradis hodnotu nejakej property v entite tak pri SaveChanges prebehne normalny update toho stlpca, ktory je namapovany na tu property. 6.5.2016
  • xxar3s : A orm naozaj usetri kopec prace, uz ziadne joiny relacie su namapovane ako kolekcie, vsetko si pises pekne objektovo, je to krasa. Ak mas kdispoziciii LINQ alebo podobne api tak naozaj sql potrebujes len vynimocne. 6.5.2016
  • podhy : harrison314: neznám rozhodně všechna ORM, ale co mám tak přehled tak ve většině člověk neudělá věci jako rekurzivní dotazy (nebo obecně CTE) a analytické funkce + mnoho další super věcí v SQL 6.5.2016
  • Kit : @xxar3s: Měl jsem na mysli update ve stylu: Přičti 200 Kč do sloupce "částka". V SQL se to dělá jediným příkazem v jedné transakci, v ORM je to na několik řádek a ještě se tomu musí explicitně říct, že to musí udělat v transakci. 7.5.2016
  • harrison314 : @podhy: ano CTE v EF nespravis, no vytvarat komplikovane dopyty zvlada v pohode. Take veci, ked potrebujes CTE, analtyzcke dotazy, by som na ORM nepouzival, ked chcem s tymto pouzit ORM, tak potom o zabalit do stored procedury a volat tak. prosto je treba vediet kedy a ake ORM pouzit a kedy nie. 7.5.2016
  • harrison314 : @Kit: to zalezi na ORM, napriklad EF robi zmeny v jednej transkacii implicitne. 7.5.2016
  • Honza Břešťan : @harrison314: Do cele te debaty se zapojovat nechci, jen bych si daval pozor na EF a transakce. SaveChanges se v transakci provedou, ale queries stoji mimo transakce, stejnetak vicenasobne volani SaveChanges. Starsi EF (nevim jak EF7) neumi pokud vim udelat update jako jednu akci, musi se zeptat DB na entitu a az pak provest zmenu, ktera samotna je v transakci - vytazeni entity ne. Tady je prostor pro data race. Co je jeste horsi, tohle zavisi na provideru - takhle se chova EF nad SQL Serverem, ale nevim, jestli je to stejne pro postgres, MySQL... A muzu si napsat vlastni provider, ktery ma porad stejny C# interface, ale jine chovani... 7.5.2016
  • harrison314 : @Jan Břešťan: to sa da vyriesit pouzitim TransactionScope, alebo explicitnej DB transakcii. A k update, je to podla mna spravny postup, ide predsa o objektovo relacne mapovanie, preto je logicke, ze v tom nevies spravit napriklad atimicky inkrement pomocou update. 7.5.2016
  • Kit : @harrison314: Neschopnost atomického inkrementu mi právě připadá nelogická a z mého pohledu to diskvalifikuje všechna ORM, která to neumí. To raději budu používat Redis, který ORM nepotřebuje. 7.5.2016
  • harrison314 : @Kit: schopnost inkrementu obcas potrebna (aj ked osobne som ju v praxi nepotreboval vyse 3 rokov), ale do ORM nepatri, ak ho od neho yzadujes, tak si tu technologiu nepochopil. 7.5.2016
  • Kit : @harrison314: To se mi ulevilo. Z toho mi vyplývá, že skutečně žádné ORM nepotřebuji a bylo by pro mne vyloženě škodlivé snažit se používat něco takového. 7.5.2016
  • cmelo : plne objektovy model aplikacie je daleko lahsie udrziavatelny ako nejaka spagetarna sqliek, bez doctrine by som si uz nevedel predstavit robit nejaky ten vacsi projekt :) 10.5.2016
  • Kit : Proč by SQL mělo být špagetárnou? Naopak mi vychází čisté SQL objektovější než práce s běžnými ORM, které mají do objektovosti hodně daleko. 10.5.2016
  • cmelo : nie sql ale cely projekt je spagetarna kde cela logika je implmenetovana v kadejakych god class servisach ktore priamo vykonavaju nejake zmeny v databaze 10.5.2016
  • Taco : @cmelo: Vykašlete se na to zbožňování OOP. Stejně to stojí a padá na tom, zda programátor přemejšlí nebo ne. Můžeš mět krásný procedurální kód a ohavné OOPeklo. 10.5.2016
  • Kit : @cmelo: A to je špatně, když se SQL dotazy volají v metodách servisní vrstvy? 10.5.2016
  • harrison314 : @cmelo: ale to nie je chyba SQL-ka, to je chyba programatora 11.5.2016
  • cmelo : @Kit netusim vobec aku maju strukturu tvoje projekty, ked ti to vyhovuje tak nie je o com, podobny pristup som pouzival aj ja kym mi nenarastol projekt do takeho stavu, ze to uz dalej nebolo udrzatelne, preto odporucam pouzit orm pri vacsich projektoch, ulahci ti to kopu problemov ale na druhej strane "with great power comes great responsibility" 11.5.2016
  • SpaceAngel : @Taco: a ze se mame vykaslat na zboznovani OOP rikas zrovna ty Martine :-) 11.5.2016
  • Taco : @SpaceAngel: Nezapomeň na tu druhou část mého prohlášení Petře. 11.5.2016
odkaz
6 Žížala
odpověděl/-a 16.5.2016
 
upravil/-a 16.5.2016

Zdravím.
Před několika měsíci jsem dokončil výběr frameworku pro novou verzi eshopu. Po přečtení mnoha recenzí, pár dotazech na různých fórech a několika testech, jsem zakotvil u Yii2. Původně jsem přemýšlel nad Phalconem, ale jeho nástroje pro vytváření koster modelů jsou docela slabé a bylo tam pár dalších věcí.

Proč jsem zakotvil u Yii2:
Je rychlé a to včetně ORM - rychlejší už je jenom Phalcon a čisté SQL.
Přímá podpora bootstrapu
a pár dalších věcí

Co mě na Yii s*re?
Nutnost dodržovat mnoho konvencí.

A co se mě na Yii líbí?
Např. tohle:
Definice validačních pravidel a labelů pro atributy v modelu

public function rules()
  {
    return [
        [['name', 'surname', 'street', 'housenumber', 'city', 'postcode', 'countrykey', 'email', 'phone', 'customerid'], 'required','message'=>"Povinná položka!"],
        [['customerid'], 'integer'],
        [['name'], 'string', 'max' => 29],
        [['surname'], 'string', 'max' => 30],
        [['street', 'city'], 'string', 'max' => 50],
        [['housenumber'], 'string', 'max' => 10],
        [['countrykey'], 'string', 'max' => 3],
        [['company'], 'string', 'max' => 40],
        [['sex'], 'string', 'max' => 1],
        [['email'], 'string', 'max' => 60],
        [['email'], 'email'],
        [['phone'], 'string', 'max' => 20],
        [['postcode'],'match','pattern' => '/^[1-9]{1}[0-9]{4}$/i','message'=>"Neplatné PSČ"],
        [['phone'],'match','pattern' => '/^(([+]{1})|(0{0,2}))[0-9 ]{8,15}$/i','message'=>"Neplatné telefonní číslo"],
    ];
  }
 
  /**
   * @inheritdoc
   */
  public function attributeLabels()
  {
    return [
        'addressid' => 'Addressid',
        'name' => 'Jméno',
        'surname' => 'Příjmení',
        'street' => 'Ulice',
        'housenumber' => 'Číslo popisné',
        'city' => 'Město',
        'postcode' => 'PSČ',
        'countrykey' => 'Stát',
        'company' => 'Firma',
        'sex' => 'Sex',
        'email' => 'Email',
        'phone' => 'Telefon',
        'customerid' => 'Customerid',
    ];
  }

View

$form = ActiveForm::begin([
            'id' => 'login-form'
            ,'fieldConfig' => 
               function($model,$attribute){
                 $options = [];
                 $options['template'] = "{input} {error}";
                 $options['hintOptions'] = ['tag'=> 'span'];
                 $options['errorOptions'] = ['tag'=> 'span','class'=>'red bold'];
                 return $options;
              }
        ]);
        ?>        
...
            <tr>
                <td class='right'>Oslovení</td>
                <td colspan='2'><?=$form->field($contactAddress, 'sex')->radioList(array('M'=>'pan','F'=>'paní'));?></td>
            </tr>
            <tr>
                <td class='right'><?=$contactAddress->getAttributeLabel('company')?></td>
                <td colspan='2'><?=$form->field($contactAddress, 'company');?></td>
            </tr>
...
 
<?php 
 
        ActiveForm::end();
        ?>

A v controleru tohle

...
$contactAddress = CustomerContactAddresses::findOne ( [ 
        "customerid" => $this->customerSession->getCustomerid () 
    ] );
...
//natáhne data z POSTU
$contactAddress->load ( \Yii::$app->request->post () );
//udělám validaci podle pravidel v modelu, základní pravidla Gii v modelu vygeneruje samo
//pokud použiji vestavěné validátory, ActiveForm vygeneruje i validační JS kód
$customerValid = $customer->validate ();

P.S. Vykašlete se na kritiku polí modelu, tohle je jeden z důvodů proč ten eshop předělávám po mém předchůdci.

Pro zobrazení všech 8 odpovědí se prosím přihlaste:

Rychlé přihlášení přes sociální sítě:

Nebo se přihlaste jménem a heslem:

Zadejte prosím svou e-mailovou adresu.
Zadejte své heslo.