Lekce 3 - První aplikace v Nette

PHP Nette Framework Základy První aplikace v Nette

ONEbit hosting Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem. Vydávání, hosting a aktualizace umožňují jeho sponzoři.

Z minulé lekce, Nette sandbox a IDE, máme vše připraveno pro vývoj v Nette frameworku. V dnešním tutoriálu si tedy ukážeme tvorbu první jednoduché aplikace. Na ní si vysvětlíme základní strukturu a konfiguraci frameworku a především základy MVP.

Volba aplikace

Výběr vhodné aplikace, na které bychom si mohli demonstrovat vše potřebné, nebyl úplně snadný, ale nakonec se vítězem stala jednoduchá kalkulačka, jejíž screenshot vidíte níže. Takže když už víme v čem a co budeme dělat, tak hurá do práce! :)

Kalkulačka v Nette frameworku pro PHP

Instalace Nette

Abychom mohli začít programovat, musíme si nejdříve Nette nějakým způsobem nainstalovat. Způsobů je hned několik:

1) Klasický download a rozbalení

Nette si klasicky stáhnete a rozbalíte do dané projektové složky z oficiální stránky. Můžete k tomu využít i nějaké to IDE, jak jsme si ostatně ukazovali minule. Projekt si pojmenujte např. nette-calculator.

2) Přes Composer

Pokročilejší uživatelé mohou použít Composer, cože je nástroj na správu závislostí v PHP. Nejdříve si ho musíte opět stáhnout a nainstalovat a jak na to najdete v tomto návodu. Když už máte Composer připravený, stačí si otevřít danou projektovou složku a spustit konkrétní příkaz, který zařídí celou instalaci Nette a zkontroluje i potřebné závislosti.

Nový projekt vytvoříme příkazem:

composer create-project nette/web-project nette-calculator

Tímto příkazem se nám vytvořila základní struktura projektu ve složce nette-calculator/. K ní si pouze přidáme soubor .htaccess pro automatické přesměrování do složky www/, kde se nachází soubor index.php, kterým se celá aplikace spouští. Vše, včetně nástroje Composer, samozřejmě naleznete v přiloženém archivu.

Závislosti

Ještě si dovolím malou, ale důležitou poznámku k softwarovým závislostem. Pro instalaci Nette se předpokládá, že máte zprovozněný webový server (např. Apache) s PHP ve verzi 5.6 nebo vyšší. Pokud nevíte, jak na to, doporučuji přečíst si článek Instalace Apache, MySQL a PHP na Windows. Podrobný návod, jestli váš server splňujete všechny požadavky a jak si to ověřit, pak naleznete v minulé lekci.

Nyní stačí zadat do webového prohlížeče URL:

http://localhost/nette-calculator/

a měli byste vidět tuto základní stránku Nette webového projektu (v případě sandboxu zde budou ještě nějaké informace navíc):

Nette Web project

Pokud se vám tato stránka z nějakého důvodu nezobrazuje, pravděpodobně je něco špatně s vaší konfigurací projektu, takže doporučuji znovu poctivě projít návod i odkazy výše nebo třeba zkusit druhý způsob instalace. A když už opravdu nebudete vědět kudy kam, můžete mi vždycky napsat do komentářů pod článek ;)

MVP

Teď, když již máme vše připravené, můžeme začít programovat samotnou kalkulačku. Vyvstává důležitá otázka a to, odkud začít? Za sebe mohu doporučit 3 způsoby postupu:

1) Postup od Pohledu

V tomto postupu se nejdříve zamyslíme, co chceme vlastně na dané webové stránce zobrazit. Podle toho si navrhneme šablonu (template), kterou ale musíme vyplnit potřebnými daty. Takže následně navrhneme presenter, který potřebná data předává do šablony. Ten ale musí tato data získat z modelu, takže nakonec naprogramuje onen model, který tato potřebná data dodává např. z databáze.

2) Postup od Modelu

Zde je postup v podstatě opačný. Nejdříve se opět zamyslíme jaká data budeme potřebovat zobrazit. K získání těchto dat si vytvoříme model. Dále potřebujeme tato data zpracovat a předat do šablony a k tomu si opět uděláme potřebný presenter. Nakonec navrhneme šablonu, kde se získaná data zobrazí do podoby webové stránky.

3) Kombinace předchozích

Tento postup si bere z každého trochu. Vytváříme postupně šablony i modely a pak se je snažíme pomocí presenterů lepit dohromady. Tohle je asi nejpoužívanější metoda, která nabízí tu výhodu, že můžeme střídavě postupovat z obou směrů vývoje, což je v praxi asi nejpoužitelnější. Jen musí člověk dát pozor, aby se v tom neztratil, zachoval rozdělení funkčnosti modelů a presenterů a nelepil dohromady ošklivé konstrukce, které mu zkrátka vyplynuly střetem modelu a šablony.

Já v tomto případě zvolím postup číslo dvě, protože se domnívám, že se pro naši kalkulačku více hodí. Takže začneme hezky od Modelu.

Model

app/model/Cal­culatorManager­.php

Řekněme, že naše kalkulačka bude mít 4 základní operace tj. sčítání, odčítání, násobení a dělení. Tyto operace umístíme do modelu, protože nám vracejí výsledky, tedy naše data. Vytvoříme si složku app/model/, kam umístíme soubor CalculatorManager.php s naší třídou modelu CalculatorManager, která používá PHP trait Nette/SmartObject a definuje naše 4 operace:

<?php

namespace App\Model;

use Nette\SmartObject;

/**
 * Model operací kalkulačky.
 * @package App\Model
 */
class CalculatorManager
{
        use SmartObject;

        /**
         * Sečte daná čísla a vrátí výsledek.
         * @param int $x první číslo
         * @param int $y druhé číslo
         * @return int výsledek po sčítání
         */
        public function add($x, $y)
        {
                return $x + $y;
        }

        /**
         * Odečte druhé číslo od prvního a vrátí výsledek.
         * @param int $x první číslo
         * @param int $y druhé číslo
         * @return int výsledek po odčítání
         */
        public function subtract($x, $y)
        {
                return $x - $y;
        }

        /**
         * Vynásobí daná čísla a vrátí výsledek.
         * @param int $x první číslo
         * @param int $y druhé číslo
         * @return int výsledek po násobení
         */
        public function multiply($x, $y)
        {
                return $x * $y;
        }

        /**
         * Vydělí první číslo druhým bezezbytku a vrátí výsledek.
         * @param int $x první číslo
         * @param int $y druhé číslo; nesmí být 0
         * @return int výsledek po dělení bezezbytku
         */
        public function divide($x, $y)
        {
                return round($x / $y);
        }
}

Můžete si povšimnout, že jelikož jsem se rozhodl provádět operace v celých číslech, tak chci tuto vlastnost zachovat i u dělení, tudíž výsledek zaokrouhluji na celá čísla. Dále si bystřejší z vás určitě všimli, že není ošetřeno dělení nulou. To však není chyba a my se k tomu ještě vrátíme.

Základní operace bychom tedy měli, to však ještě není všechno. Jelikož by model měl být rozšiřitelný a podle MVP bychom při změně modelu nejlépe neměli měnit ani presenter, ani šablonu, přidáme si ještě jednoduché rozhraní, která nám tyto vlastnosti zajistí. Jen poznamenám, že tyto vlastnosti lze získat i pomocí reflexe, ale té se zde věnovat nechci. To znamená, že přidáme ještě tyto metody a konstanty:

// ...

/** Definice konstant pro operace. */
const
        ADD = 1,
        SUBTRACT = 2,
        MULTIPLY = 3,
        DIVIDE = 4;

/**
 * Getter pro existující operace.
 * @return array asociativní pole konstant pro operace a jejich slovního pojmenování
 */
public function getOperations()
{
        return array(
                self::ADD => 'Sčítání',
                self::SUBTRACT => 'Odčítání',
                self::MULTIPLY => 'Násobení',
                self::DIVIDE => 'Dělení'
        );
}

/**
 * Zavolá zadanou operaci a vrátí její výsledek.
 * @param int $operation zadaná operace
 * @param int $x         první číslo pro operaci
 * @param int $y         druhé číslo pro operaci
 * @return int|null výsledek operace nebo null, pokud zadaná operace neexistuje
 */
public function calculate($operation, $x, $y)
{
        switch ($operation) {
                case self::ADD:
                        return $this->add($x, $y);
                case self::SUBTRACT:
                        return $this->subtract($x, $y);
                case self::MULTIPLY:
                        return $this->multiply($x, $y);
                case self::DIVIDE:
                        return $this->divide($x, $y);
                default:
                        return null;
        }
}

// ...

Nyní jsme schopni přidat další operaci do modelu a přitom v presenteru i v šabloně nemusíme změnit v podstatě nic.

A to je z modelu i z dnešní lekce už opravdu vše. Na navazující presenter, routování, formuláře a šablony v Nette se podíváme v lekci příští, Dokončení kalkulačky v Nette :)


 

 

Článek pro vás napsal Jindřich Máca
Avatar
Jak se ti líbí článek?
22 hlasů
Autor se věnuje převážně webovým technologiím, ale má velkou zálibu ve všem vědeckém, nejen ze světa IT. :-)
Miniatura
Předchozí článek
Nette sandbox a IDE
Miniatura
Všechny články v sekci
Základy Nette frameworku
Miniatura
Následující článek
Dokončení kalkulačky v Nette
Aktivity (8)

 

 

Komentáře

Avatar
mpis
Člen
Avatar
mpis:8.7.2015 10:07

Jedna drobná připomínka nebo dotaz:

V kapitole "1) Klasický download a rozbalení" se píše

... projekt si pojmenujte nette-calculator

a v kapitole "2) Přes Composer" se píše

...Nový projekt vytvoříme příkazem:

composer create-project nette/web-project calculator-nette

Je to správně? Asi by to mělo být konzistentní, tzn. stejný název:
buď calculator-nette nebo nette-calculator.
Začátečníka to může uvádět do zmatku.

 
Odpovědět 8.7.2015 10:07
Avatar
Jindřich Máca
Tým ITnetwork
Avatar
Odpovídá na mpis
Jindřich Máca:8.7.2015 10:41

Ano, tam je chyba, ale o nic nejde, neboť projekt si můžeš pojmenovat třeba

louka-sedmikrasek

a bude to fungovat pořád stejně. :)

P.S.: Chybu samozřejmě napravím. ;)

Editováno 8.7.2015 10:42
 
Odpovědět 8.7.2015 10:41
Avatar
Aleš Kopecký:31.10.2017 21:32

Ahoj, proč jsou metody pro matematické operace public, když je pro práci s modelem určeno "rozhraní" v podobě metody calculate()?
Je v tomto případě metoda calculate() jen "něco navíc", co nemusím použít a můžu použít rovnou metody a tím tedy metody nemusí být nutně private?

 
Odpovědět 31.10.2017 21:32
Avatar
Jindřich Máca
Tým ITnetwork
Avatar
Odpovídá na Aleš Kopecký
Jindřich Máca:1.11.2017 1:06

Ahoj, je tomu přesně tak. Jsou to prostě metody, které třída chce nabízet navenek. Co pak její uživatel doopravdy použije je čistě na něm, ale jako autor třídy by se člověk měl snažit o trochu univerzálnosti a znovupoužitelnosti. :)

 
Odpovědět 1.11.2017 1:06
Avatar
Miroslav Mucha:15. března 10:03

Ahoj, v dokumentaci k PHP je uvedeno, že v případě použití switch musí být použít i příkaz break. Proč tady není?

 
Odpovědět 15. března 10:03
Avatar
dez1nd
Člen
Avatar
Odpovídá na Miroslav Mucha
dez1nd:15. března 10:08

Místo break je použitý return ;)

 
Odpovědět 15. března 10:08
Avatar
Odpovídá na dez1nd
Miroslav Mucha:15. března 10:18

Díky za odpověď, s tím jsem se nikde v dokumentaci nesetkal. Opět zjišťuji, že programování je spojeno se spoustou alternativ. :-)

 
Odpovědět 15. března 10:18
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 7 zpráv z 7.