Homebrew (Wikipedie), správce balíčků pro macOS a od verze 2.0.0 také pro Linux, byl vydán ve verzi 4.5.0. Na stránce Homebrew Formulae lze procházet seznamem balíčků. K dispozici jsou také různé statistiky.
Byl vydán Mozilla Firefox 138.0. Přehled novinek v poznámkách k vydání a poznámkách k vydání pro vývojáře. Řešeny jsou rovněž bezpečnostní chyby. Nový Firefox 138 je již k dispozici také na Flathubu a Snapcraftu.
Šestnáctý ročník ne-konference jOpenSpace se koná 3. – 5. října 2025 v Hotelu Antoň v Telči. Pro účast je potřeba vyplnit registrační formulář. Ne-konference neznamená, že se organizátorům nechce připravovat program, ale naopak dává prostor všem pozvaným, aby si program sami složili z toho nejzajímavějšího, čím se v poslední době zabývají nebo co je oslovilo. Obsah, který vytvářejí všichni účastníci, se skládá z desetiminutových
… více »Richard Stallman přednáší ve středu 7. května od 16:30 na Technické univerzitě v Liberci o vlivu technologií na svobodu. Přednáška je určená jak odborné tak laické veřejnosti.
Jean-Baptiste Mardelle se v příspěvku na blogu rozepsal o novinkám v nejnovější verzi 25.04.0 editoru videa Kdenlive (Wikipedie). Ke stažení také na Flathubu.
TmuxAI (GitHub) je AI asistent pro práci v terminálu. Vyžaduje účet na OpenRouter.
Byla vydána nová verze R14.1.4 desktopového prostředí Trinity Desktop Environment (TDE, fork KDE 3.5, Wikipedie). Přehled novinek i s náhledy v poznámkách k vydání. Podrobný přehled v Changelogu.
Bylo vydáno OpenBSD 7.7. Opět bez písničky.
V Tiraně proběhl letošní Linux App Summit (LAS) (Mastodon). Zatím nesestříhané videozáznamy přednášek jsou k dispozici na YouTube.
Ako som už spomínal, v predchadzajúcej časti seriálu sme si controller stručne predstavili, v tomto prípade sme si ukázali použitie tzv. scaffolding. V tejto časti si controller predstavíme podrobne.
Controller je tá časť aplikácie, ktorá ako prvá prichádza do styku s požiadavkami, ktoré prichádzajú do našej aplikácie z vonkajšieho sveta. Najčastejším prípadom takéhoto požiadavku z vonkajšieho sveta je URL adresa. Ak teda budeme pristupovať k našej aplikácii prostredníctvom URL, potrebujeme nejaký mechanizmus, ktorý nám na základe tejto URL určí, že aplikácia „pozná“, na aké prvky aplikácie má smerovať dané požiadavky. Takýto mechanizmus sa nazýva routing.
V minulosti sa formátu URL adresy veľká pozornosť nevenovala. Často sme boli svedkami podobných URL ako môžeme vidieť na ukážke
http://www.example.com/index.php?action=list&template=comments&page=2&order=DESC
URL adresa v takomto tvare bola možno jednoduchá pre programátora, určite však nie pre užívateľa. V súčasnosti je trend iný a hlavne moderné frameworky sa snažia vytvárať a používať tzv. user friendly URL. Príklad takejto adresy môžeme vidieť na ukážke
http://www.example.com/articles/mvc-model-view-controller-v-cakephp
Určite nám je jasné, že takáto adresa je oveľa viac čitateľnejšia a zrozumiteľnejšia nie len pre užívateľa. Bližšie štúdium o tejto problematike ponechám na samotných čitateľov, pretože by to presahovalo záber tohto článku. Avšak výhody takýchto URL sú nespochybniteľné. Ako sme už určite vytušili, CakePHP používa taktiež user friendly URL. Poďme sa teda bližšie pozrieť, akým spôsobom pristupujeme v CakePHP k našej aplikácii prostredníctvom URL
V našom prípade by URL adresa pre zobraznie článku v aplikácii v CakePHP mohla vyzerať tak, ako môžeme vidieť na obrázku vyššie. Z URL nám môže byť napríklad hneď jasné, že sa bude jednať o zobrazenie určitého článku. Obrázok taktiež demonštruje fungovanie routingu v samotnom CakePHP. Prvá časť adresy označená zelenou farbou nám určuje konkrétny controller v našej aplikácii, druhá časť označená červenou farbou nám určuje konkrétnu akciu v controlleri a posledná časť označená modrou farbou nám určuje parameter vkladaný do tejto akcie. Aby sme si vedeli túto situáciu predstaviť konkrétne, pozrime sa na nasledovný kód, ktorý by bol vykonaný pri použití URL adresy z obrázku:
class ArticlesController extends AppController{ var $name="Articles"; function show($id){ $this>set("article",$this>Article>findById($id)); } }
Mechanizmus routingu by zabezpečil, že by sa zavolala metóda show triedy ArticlesController a zároveň by bol metóde predaný parameter s hodnotou 43.
CakePHP nám v súvislosti s routingom ponúka ešte jednú veľmi užitočnú vlastnosť, a to sú tzv. routovacie pravidlá. Na základe týchto pravidiel môžeme ovplyvňovať samotné routovanie a v neposlednom rade nás routovacie pravidlá zbavujú povinnosti ručne modifikovať súbory .htaccess, čím nám značne uľahčujú prácu, pretože používajú oveľa prehľadnejšiu syntaxu. Treba však poznamenať, že routavacie pravidlá zďaleka nenahradzajú možnosti súboru .htaccess, pretože to nie je ani ich cieľom. Ich cieľom je poskytnúť z jednodušenú syntaxu pri pravidlách, ktoré sa týkajú routovania a spracovávania samotných URL adries.
Samotné routovacie pravidlá sa definujú v súbore app/config/routes.php. Pozrime sa na ukážkový kód
Router::connect('/sites/*', array('controller' => 'articles', 'action' => 'index')); Router::connect('/', array('controller' => 'articles', 'action' => 'index'));
Pomocou vyššie uvedených pravidiel sme určili, že URL v tvare www.example.com/sites/* (kde znak * značí ľubovoľný tvar zvyšku adresy) bude routovaná na controller articles a že sa bude v tomto controlleri volať metóda index. Taktiež sme určili, že URL v tvare www.example.com bude routovaná na vyšie spomínaný controller articles a jeho metódu index. Podrobné vysvetlenie všetkých možností použitia routovacích pravidiel je nad rámec tohto článku, ale určite v budúcnosti pripravím článok, ktorý vás kompletne prevedie svetom routovacích pravidiel v CakePHP.
Na záver tejto časti pripomeniem, že celý mechanizmus spracovávania požiadavku v CakePHP som rozoberal v článku MVC model view controller v CakePHP.
Od minulého článku máme vytvorené jednotlivé controllere, a to konkrétne ArticlesController, UsersController, CommentsController a TagsController. Avšak ako môžeme vidieť, naše controllere neobsahujú žiadne metódy resp. akcie, ktoré sú potrebné na správne fungovanie aplikácie tak, ako sme to spomínali v časti preberanej vyššie (aplikácia nám samozrejme fungovala aj tak, pretože sme využili scaffolding). Poďme si preto jednotlivé metódy vytvoriť a pripraviť si tak pôdu pre ich zobrazenie vo view.
V controlleri ArticlesController si vytvoríme dve metódy index a view, kde prvá bude reprezentovať akciu zobrazenie všetkých článkov a druhá bude reprezentovať akciu zobrazenie konkrétneho článku. Kód bude vyzerať následovne
class ArticlesController extends AppController { var $name = 'Articles'; var $helpers = array('Html', 'Form'); function index() { $this->set('articles', $this->paginate()); } function view($id = null) { if (!$id) { $this->Session->setFlash(__('Invalid Article.', true)); $this->redirect(array('action'=>'index')); } $this->set('article', $this->Article->read(null, $id)); } }
V controlleri CommentsController si vytvoríme 3 metódy, kde metóda index sa bude starať o zobrazenie všetkých komentárov, druhou metódou bude metóda view, ktorá sa bude starať o zobrazenie konkrétneho komentára a poslednou treťou metódou bude metóda add, ktorá nám pridá nový komentár. Kód bude vyzerať následovne:
class CommentsController extends AppController { var $name = 'Comments'; var $helpers = array('Html', 'Form'); function index() { $this->Comment->recursive = 0; $this->set('comments', $this->paginate()); } function view($id = null) { if (!$id) { $this->Session->setFlash(__('Invalid Comment.', true)); $this->redirect(array('action'=>'index')); } $this->set('comment', $this->Comment->read(null, $id)); } function add() { if (!empty($this->data)) { $this->Comment->create(); if ($this->Comment->save($this->data)) { $this->Session->setFlash(__('The Comment has been saved', true)); $this->redirect(array('action'=>'index')); } else { $this->Session->setFlash(__('The Comment could not be saved. Please, try again.', true)); } } $articles = $this->Comment->Article->find('list'); $this->set(compact('articles')); } }
Posledným upravovaným controllerom bude controller TagsController, ktorému pre jednoduchosť vytvoríme len dve metódy, metóda index ktorá nám zobrazí všetky dostupné tagy a metóda view, ktorá nám zobrazí všetky články prislúchajúce k danému tagu. Kód bude vyzerať následovne:
class TagsController extends AppController { var $name = 'Tags'; var $helpers = array('Html', 'Form'); function index() { $this->Tag->recursive = 0; $this->set('tags', $this->paginate()); } function view($id = null) { if (!$id) { $this->Session->setFlash(__('Invalid Tag.', true)); $this->redirect(array('action'=>'index')); } $this->set('tag', $this->Tag->read(null, $id)); } }
K vyššie uvedeným kódom bližšie vysvetlím význam niektorých použitých metód, ktoré majú pre správne pochopenie celého mechanizmu zásadný význam.
Metódou set() posielame dáta do view. Metóda prijíma dva parametre, kde prvý označuje názov premennej vo view a druhý parameter sú samotné dáta uložené do premennej s názvom určenom v prvom parametri (bližšie si túto časť vysvetlíme neskôr, kedy budeme dáta zobrazovať).
Metóda paginate() sa nám stará o stránkovanie veľkého množstva dát (túto vlastnosť si predstavíme v niektorej z ďalších častí nášho seriálu).
Metóda Session->setFlash() nám nastaví chybovú hlášku pre layout, ktorú môžeme jednoducho v našom layoute zobraziť na mieste, kde budeme chcieť.
Metóda redirect() sa postará o presmerovanie behu našej aplikácie buď pomocou zadanej URL adresy alebo pomocou určenia controllera a akcie.
Premenná $this->data reprezentuje dáta odoslané formulárom z view.
Určite vás napadlo, že sme v našich controlleroch nikde neuvádzali akcie pre pridanie článku, pridanie tagu, administrácie užívateľov atď. Je to náš zámer, pretože dané akcie patria do administračného rozhrania, ktorému sa budeme venovať v nasledujúcej časti seriálu.
Už sme si spomenuli metódu, ktorá nám posiela dáta do view pochádzajúce z našich modelov. Správne tušíte, že sa jedná o metódu set() a pochopenie jej práce je pre ďalšie časti kľúčové. Ako som spomenul, príjíma dva parametre, prvý parameter je názov premennej vo view a druhým parametrom sú samotné dáta, ktoré sa vložia do premennej s názvom určenom v prvom parametri. Aby sme neostali len pri teórii, poďme si ich význam ukázať na príklade.
Zoberme kód nášho controllera ArticlesController a jeho metódu view, ktorá reprezentuje akciu pre zobrazenie konkrétneho článku. Užívateľ zadá do prehliadača URL www.example.com/articles/view/1, čím určí, že chce zobraziť článok s id 1. Mechanizmus routingu správne vyhodnotí URL a určí, že sa vykoná metóda view v controlleri ArticlesController. Táto metóda najprv otestuje, či sme zadali nejaké id článku. Ak áno, pomocou modelu vyberie dáta z tabuľky articles ($this->Article->read(null, $id)) a následne ich vloží do view pod premennou article ($this->set(‚article‘, $this->Article->read(null, $id))). Potom už je naša práca veľmi jednoduchá a dáta možeme zobraziť.
Súbory s našimi šablónami sa ukladajú do adresára app/views. V našom prípade pre zobrazenie článku to bude adresár app/views/articles/view.ctp. Náš súbor view.ctp, ktorý zobrazuje konkrétny článok, by mohol vyzerať následovne:
<div class="articles view"> <h2><?php __('Article');?></h2> <dl><?php $i = 0; $class = ' class="altrow"';?> <dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Id'); ?></dt> <dd<?php if ($i++ % 2 == 0) echo $class;?>> <?php echo $article['Article']['id']; ?> </dd> <dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Title'); ?></dt> <dd<?php if ($i++ % 2 == 0) echo $class;?>> <?php echo $article['Article']['title']; ?> </dd> <dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Text'); ?></dt> <dd<?php if ($i++ % 2 == 0) echo $class;?>> <?php echo $article['Article']['text']; ?> </dd> <dt<?php if ($i % 2 == 0) echo $class;?>><?php __('User'); ?></dt> <dd<?php if ($i++ % 2 == 0) echo $class;?>> <?php echo $html->link($article['User']['id'], array('controller'=> 'users', 'action'=>'view', $article['User']['id'])); ?> </dd> <dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Created'); ?></dt> <dd<?php if ($i++ % 2 == 0) echo $class;?>> <?php echo $article['Article']['created']; ?> </dd> </dl> </div>
Teraz nám už je jasné, akým spôsobom zobraziť dáta vo view. V controlleri sme si vložili do view dáta pod premennou article a vo view sme na základe tejto premennej dáta jednoducho zobrazovali (napr. $article[‚Article‘][‚title‘] zobrazí titulok článku). Ešte poznamenám, že nám nemusí byť jasné, aký význam má metóda __(‚Created‘). Táto metóda súvisí s internacionalizáciou stránky a CakePHP na toto myslí už od počiatku vývoja aplikácie. Bližšie sa o internacionalizácii môžete dočítať v článku Viacjazyčný web v cakePHP.
Už vieme, ako vložiť dáta do view. Poďme sa pozrieť nato, v akom formáte sa nám dáta z modelu do view dostávajú. Model všeobecne mapuje dáta do viacrozmerných polí. V podstate nám nastávajú dve možnosti pri vkladaní dát z modelu do view. Prvou možnosťou je, že nám model vráti jeden záznam, a druhou možnosťou je, že nám model vráti viac záznamov. Obidva prípady si ukážeme priamo na príklade.
Pozrime sa na situáciu, kedy nám model vráti jeden záznam. Predstavme si, že chceme zobraziť jeden článok, formát dát bude nasledovný:
Array ( [Article] => Array ( [id] => 46 [seo_link] => 5-tvorime-cms-s-cakephp-controller-a-view [title] => 5. Tvoríme CMS s CakePHP - Controller a View [intro_text] => V predchádzajúcej časti seriálu sme si navrhli a vytvorili databázu... ) )
Ako môžeme vidieť vyššie, model nám vratil dvojrozmerné pole, kde prvý index je názov modelu, z ktorého data pochádzajú, a druhý index je názov stĺpca v databázovej tabuľke.
Odlišná situácia nastane, keď nám model vracia viac záznamov. Predstavme si, že chceme zobraziť zoznam článkov, formát dát bude nasledovný
Array ( [0] => Array ( [Article] => Array ( [id] => 46 [seo_link] => 5-tvorime-cms-s-cakephp-controller-a-view [title] => 5. Tvoríme CMS s CakePHP - Controller a View [intro_text] => V predchádzajúcej časti seriálu sme si navrhli a vytvorili databázu... ) ) [1] => Array ( [Article] => Array ( [id] => 41 [seo_link] => ako-poslat-email-s-prilohou [title] => Ako poslať email s prílohou [intro_text] => Nedávno som v jednom z mojich projektov riešil situáciu, kedy bolo potrebné k odosielanému emailu pripojiť aj prílohu... ) ) )
Ako môžeme vidieť vyššie, model nám vrátil trojrozmerné pole, kde prvý index určuje index záznamu v poli v rozmädzí od [0;n-1], kde n-1 je počet vrátených záznamov. Druhý index je názov modelu, z ktorého dáta pochádzajú, a posledný tretí index je názov stĺpca v databázovej tabuľke.
Treba ešte poznamenať, že model nám môže vrátiť aj zložitejšie štruktúry, avšak práca s nimi je obdobná. Keď si nebudeme istý formátom dát vo view, môžeme použiť metódu var_dump() resp. pri zapnutom debug móde metódu debug() priamo z CakePHP.
Týmto je táto časť nášho seriálu u konca. Jej cieľom bolo pochopenie základných princípov archiktúry MVC, a to konkrétne controller a view. Nedotkli sme sa niektorých tém, ktoré s danými časťami súvisia, akú sú napr. helpery, komponenty atď. Nemusíte sa obávať, určite sa k nim dostaneme v niektorej z ďalších častí.
Rád uvítam vaše námety a pripomienky k článku.
Nástroje: Tisk bez diskuse
Tiskni
Sdílej:
Prvy test - bitova rotace echo 8 >> 2 2 Branch analysis from position: 0 Return found filename: Command line code function name: (null) number of ops: 4 compiled vars: none line # op fetch ext return operands ------------------------------------------------------------------------------- 1 0 SR ~0 8, 2 1 ECHO ~0 2 RETURN null 3* ZEND_HANDLE_EXCEPTION
Druhy test - deleni echo 8 / 4 2 Branch analysis from position: 0 Return found filename: Command line code function name: (null) number of ops: 4 compiled vars: none line # op fetch ext return operands ------------------------------------------------------------------------------- 1 0 DIV ~0 8, 4 1 ECHO ~0 2 RETURN null 3* ZEND_HANDLE_EXCEPTIONPokud by optimalizace byla bezpredmetna, PHP by v prvem pripade nepouzilo shift right, ale div a pokud by si to kompilator umel domyslet, v druhem pripade by byl SR (Shift Right) a ne DIV, takze laskave prestante sirit bludy, pane __dark__
Treti test - modulus echo 7 % 2 1 Branch analysis from position: 0 Return found filename: Command line code function name: (null) number of ops: 4 compiled vars: none line # op fetch ext return operands ------------------------------------------------------------------------------- 1 0 MOD ~0 7, 2 1 ECHO ~0 2 RETURN null 3* ZEND_HANDLE_EXCEPTION Ctvrty test - and echo 7 & 1 1 Branch analysis from position: 0 Return found filename: Command line code function name: (null) number of ops: 4 compiled vars: none line # op fetch ext return operands ------------------------------------------------------------------------------- 1 0 BW_AND ~0 7, 1 1 ECHO ~0 2 RETURN null 3* ZEND_HANDLE_EXCEPTION
A protože jsi to nepsal, tak jedna promarněná instrukce na 0.00005 ms je vedle zbytečného SQL dotazu na 10 ms opravdu bezpředmětná je. Takovouto optimalizací snižuješ čitelnost kódu, takže tím plýtváš čas programátora, který je nesrovnatelně dražší než dva takty procesoru 3× za sekundu. Souhlasím s tím, že kód by se měl být slušně napsaný a efektivní, ale všeho s mírou. Občas je prostě lepší zvolit postup, který není úplně nejefektivnější, ale je čitelnější a lépe udržovatelný.Aha, takže mi chcete říct, že stráky, které potřebují desítky SQL dotazů pro zobrazení zachrání nějaké & 1 místo % 2 ?Nic takoveho jsem nikde nepsal, pouze uvadim, ze tato optimalizace neni bezpredmetna.
unsigned int a; a /= 8;Toto si překladač zcela jistě upraví na bitovou operaci.
int some_func(int x) {
int y;
...
x /= y;
...
return x;
}
Ocekaval jsem, ze navstivis google.cz a napises tam "freez", asi jsem ocekaval prilis.Přišlo mi zbytečné prolistovávat se katalogem mrazáků
Pri detekci zda je cislo sude ci liche neexistuje zadne "jakmile chci zmenit 2 za 3...", v ostatnich pripadech plati pravidlo neprve vse promyslet, pote zvolit optimalni algoritmus, nikoliv upravovat a upravovat, dokud to nebude vypadat, ze to nejak funguje.Tohle nevysvětluj mě, ale zákazníkům.
Diskutuje se zde specificky o x86 a x86_64, pricemz tam je v tomto pripade vzdy rychlejsi logicka operace a nezalezi na poradi instrukci.PHP funguje i na jiných architekturách. Proč se omezovat zrovna na tu, co máš na stole ty? ps: Tvůj blog jsem našel.
...Ze ja s nekym takovym vubec ztracim cas. Ten omozenec to proste nedokaze pochopit.
Pokud jsi někdy viděl zákazníka, který ví co chce a nemění požadavky častěji než ponožky, celkem ti závidím. Jinak prostě nezbývá, než psát tak, aby se to dalo lehce upravovat i za cenu, že to nebude nejoptimálnější.Tohle nevysvětluj mě, ale zákazníkům.To bys mel vedet ty, ne zakaznik.
Už sme si spomenuli metódu, ktorá nám posiela dáta do view pochádzajúce z našich modelov. Správne tušíte, že sa jedná o metódu set() a pochopenie jej práce je pre ďalšie časti kľúčové.Podstatna je informacia, ze metoda set() je pre dlasie pokracovanie klucova. Nie je potreba spominat, ze sme si ju o 10 riadkov vyssie popisaly (vyznam by to malo, keby sa o danej metode pisalo v starsom clanku). Podobne "navraty" sa vo vasich clankoch objavuju viackrat. Neviem mozno ste platey za pocet slov ale takto zbytocne znizujete kvalitu svojho clanku, ktory je o zaujimavej teme. Prosim neberte si moju krityku zle. Snazim sa Vam ukazat, kde robite najvecsie (okate) chyby, aby boli Vase clanky kvalitnejsie. Mozno by sa hodilo, keby niekto zo starsich a skusenejsich prispievatelov obcas presiel clanky inych autorov a zkrityzoval ich (Alebo vytvorit bokom nieaku stranku, ktora by obsahovala veci, ktorym sa pri tvorbe technickeho clanku vyhnut??) PS :: Nie som novinar ani spisovatel a tak je mozne, ze sa mylim. Len sa pokusam zdoraznit vecy v textu ktore ma vyrusuju od citania.
mozno ste platey za pocet slovsi prosim vas odpuste, je to trapne. Ja rad privitam namety a pripomienky, takze sa budem snazit z vasich pripomienok poucit. A na abclinuxu je predsa email konferencia, kde si mozes precitat clanky este pred vydanim a napisat k nim svoje pripomienky.
Pripomienky typu mozno ste platey za pocet slov si prosim vas odpuste, je to trapne.Ospravedlnujem sa. nemyslel som to v zlom.
A na abclinuxu je predsa email konferencia, kde si mozes precitat clanky este pred vydanim a napisat k nim svoje pripomienky.To je sice pravda, ale tato konference je pouze pro aktivní autory.
Neviem mozno ste platey za pocet slovDélka sice roli hraje, ale kvalita samozřejmě také.