Vánoční nadílka Vánoční nadílka
Až 80% zdarma! Předvánoční BLACK FRIDAY akce. Více informací

Lekce 15 - Tvorba knihoven v PHP

PHP Základní konstrukce Tvorba knihoven v PHP American English version English version

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.

V minulé lekci, Tvorba vlastních funkcí v PHP, jsme se naučili deklarovat vlastní funkce. V dnešním PHP tutoriálu se je naučíme logicky seskupovat do knihoven a vše si prakticky vyzkoušíme na jednoduché aplikaci.

Tvorba knihoven

Funkce obvykle nezapisujeme jen tak někam do stránky, ale vkládáme je do knihoven. Knihovna není nic jiného, než soubor s příponou .php, ve kterém na začátku otevřeme PHP sekvenci a poté do něj pod sebe vložíme několik funkcí. Knihovna by samozřejmě měla obsahovat jen ty funkce, které souvisí s jejím zaměřením. Pro každé zaměření si vytvoříme jinou knihovnu (např. emaily.php, matematika.php, databaze.php...) a vyvarujeme se tvoření "božských knihoven" všeho v jednom souboru.

Vytvořme si knihovnu k posílání emailů. Bude zatím obsahovat jen jednu funkci a tou bude ta z minulého dílu. Obsah knihovny emaily.php bude následující:

<?php

/*
 * Knihovna pro práci s emaily
 */

function odesliEmail($adresa, $predmet, $odesilatel, $zprava)
{
        $hlavicka = 'From:' . $odesilatel;
        $hlavicka .= "\nMIME-Version: 1.0\n";
        $hlavicka .= "Content-Type: text/html; charset=\"utf-8\"\n";
        $predmet = 'Nová zpráva z mailformu';
        $uspech = mb_send_mail($adresa, $predmet, $zprava, $hlavicka);
        return $uspech;
}

Funkcí můžeme do knihovny vložit samozřejmě kolik chceme, mohla by zde být např. ještě funkce, co kontroluje správnost zadané emailové adresy. Všimněte si, že na konci souboru chybí uzavření PHP sekvence. Je to z toho důvodu, že v knihovně je jen PHP kód, direktiva se sama uzavře, až se PHP dostane na konec souboru. Jedná se také o doporučení, protože pár bílých znaků za uzavřením PHP sekvence by mohlo v určitých případech vyvolat nepříjemné chyby.

Jakmile máme knihovnu hotovou, jednoduše ji uložíme do složky s webem a v souborech, ve kterých ji budeme chtít použít, ji načteme. Asi vás nepřekvapí, že načtení knihovny provedeme pomocí funkce require(). O té víme, že do souboru vloží obsah jiného souboru a to tak, že vykoná případné vložené skripty. V našem případě tedy deklaruje funkce, které knihovna obsahuje. Abychom se vyvarovali toho, že knihovnu omylem někde načteme i tehdy, když už je načtená, použijeme variantu require_once(). Ta nic neudělá v případě, že knihovna již byla načtena. Samozřejmě platí, že pokud zobrazujeme celý web pomocí index.php, stačí knihovnu načíst jen jednou zde. Pokud máme však oddělené stránky, musíme ji načíst na začátku každé stránky, ve které chceem funkce z knihovny používat.

require_once('emaily.php');
odesliEmail('[email protected]', 'Test emailu', '[email protected]', 'Text zprávy');

Funkce je deklarována v knihovně a nám stačí již jen knihovnu načíst a začít funkci používat. Pokud budete tento princip využívat, budou vaše aplikace velmi přehledné. Pojďme si procvičit práci s textovými řetězci a za tímto účelem si vytvořme vlastní knihovnu.

Analyzátor vět

Naprogramujme si jednoduchý analyzátor vět, kterému zadáme větu a on vypíše počet znaků ve větě, dále počet samohlásek, počet souhlásek a počet ostatních znaků.

Knihovna

Začneme knihovnou. Víme, že pro počet znaků máme funkci mb_strlen(). Zjištění počtu samohlásek a souhlásek za nás však již PHP neudělá a proto si na to založíme knihovnu. Pojmenujeme ji analyzaVet.php. Její obsah bude následující:

<?php

/**
 * Knihovna pro analýzu vět
 */

function pocetSamohlasek($text)
{
    $text = mb_strtoupper($text);
    $delka = mb_strlen($text);
    $samohlasky = array('A', 'E', 'I', 'O', 'U', 'Y');
    $pocet = 0;
    for ($i = 0; $i < $delka; $i++)
    {
        $znak = mb_substr($text, $i, 1);
        if (in_array($znak, $samohlasky))
            $pocet++;
    }
    return $pocet;
}

function pocetSouhlasek($text)
{
    $text = mb_strtoupper($text);
    $delka = mb_strlen($text);
    $souhlasky = array('B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'V', 'W', 'X', 'Z');
    $pocet = 0;
    for ($i = 0; $i < $delka; $i++)
    {
        $znak = mb_substr($text, $i, 1);
        if (in_array($znak, $souhlasky))
            $pocet++;
    }
    return $pocet;
}

Každá funkce si nejprve definuje proměnné $text a $delka, kde je délka textu ve znacích. Do pole $samohlasky (resp. $souhlasky) si uloží znaky, jejichž počet nás zajímá. Dále si vytvoří proměnnou $pocet, do které dá počáteční hodnotu 0. Potom cyklem for projede všechny znaky a aktuální znak vždy uloží do proměnné $znak. Pomocí funkce in_array() zjistí, zda pole obsahuje daný znak. Pokud ano, započítá ho. Dále nezbývá nic jiného, než výslednou hodnotu vrátit.

Jistě jste si všimli, že se obě funkce liší jen obsahem pole. Můžeme kód výrazně optimalizovat tím, že vytvoříme univerzální funkci, která bere na vstupu řetězec a znaky, které nás zajímají. Tuto funkci budeme poté volat ve funkcích pocetSamohlasek() a pocetSouhlasek().

Obsah souboru s identickou funkcionalistou by mohl vypadat takto:

<?php

/**
 * Knihovna pro analýzu vět
 */

function pocetZnaku($text, $znaky)
{
    $text = mb_strtoupper($text);
    $delka = mb_strlen($text);

    $pocet = 0;
    for ($i = 0; $i < $delka; $i++)
    {
        $znak = mb_substr($text, $i, 1);
        if (in_array($znak, $znaky))
            $pocet++;
    }
    return $pocet;
}

function pocetSamohlasek($text)
{
    $samohlasky = array('A', 'E', 'I', 'O', 'U', 'Y');
    return pocetZnaku($text, $samohlasky);
}

function pocetSouhlasek($text)
{
    $souhlasky = array('B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'V', 'W', 'X', 'Z');
    return pocetZnaku($text, $souhlasky);
}

Poměrně zajímavou úlohu jsme rozdělili do 3 funkcí. Vidíme, že funkce jsou našimi spojenci a dokáží nám zjednodušit život. Stačí totiž jen zavolat tu samou funkci s jinými parametry místo toho, abychom kopírovali celý kód znovu.

Nyní si vytvoříme soubor analyza.php, kam vložíme formulář na zadání věty, načteme knihovnu a pomocí ní zjistíme dané počty:

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Analyzátor vět</title>
    </head>
    <body>
        <h1>Analyzátor vět</h1>

        <?php
            require_once('analyzaVet.php');

            if ($_POST)
            {
                if (isset($_POST['zprava']))
                {
                    $zprava = $_POST['zprava'];
                    $znaku = mb_strlen($zprava);
                    $samohlasek = pocetSamohlasek($zprava);
                    $souhlasek = pocetSouhlasek($zprava);
                    echo('<h2>Výsledek analýzy:</h2>');
                    echo('<table>');
                    echo('<tr><td>Znaků</td><td>' . htmlspecialchars($znaku) . '</td></tr>');
                    echo('<tr><td>Samohlásek</td><td>' . htmlspecialchars($samohlasek) . '</td></tr>');
                    echo('<tr><td>Souhlásek</td><td>' . htmlspecialchars($souhlasek) . '</td></tr>');
                    echo('</table>');
                }
            }

        ?>

        <p>Zadejte větu k analýze</p>
        <form method="post">
            <textarea name="zprava"></textarea><br />
            <input type="submit" value="Analyzovat" />
        </form>
    </body>
</html>

Výsledek:

Analyzátor vět
localhost

Zkuste se zamyslet nad tím, jak by vypadal zdrojový kód bez použití funkcí (nebyl by vůbec hezký). Diakritiku jsem neřešil, můžete si ji do polí přidat. Na knihovny se obvykle také vytváří nějaká složka, když je jich více.

Obecně je snaha co nejvíce logiky přesunou do knihoven (později objektů) a v souborech s HTML stránkou mít opravdu jen to nejnutnější. Toto je úplný základ oddělení logiky a výstupu. Časem se dostaneme např. k MVC architektuře, kde je tento princip doveden do dokonalosti. Knihovny a funkce si bohatě procvičíme v dalším seriálu o práci s databázemi.

Kam dál?

Náš arzenál znalostí je nyní připraven k tomu, abychom se pustili do databází. Naše výuka PHP pokračuje kurzem Databáze v PHP pro začátečníky.


 

Stáhnout

Staženo 445x (1.31 kB)
Aplikace je včetně zdrojových kódů v jazyce php

 

 

Článek pro vás napsal David Čápka
Avatar
Jak se ti líbí článek?
19 hlasů
Autor pracuje jako softwarový architekt a pedagog na projektu ITnetwork.cz (a jeho zahraničních verzích). Velmi si váží svobody podnikání v naší zemi a věří, že když se člověk neštítí práce, tak dokáže úplně cokoli.
Unicorn College Autor sítě se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.
Miniatura
Předchozí článek
Tvorba vlastních funkcí v PHP
Miniatura
Všechny články v sekci
Základní konstrukce jazyka PHP
Aktivity (6)

 

 

Komentáře
Zobrazit starší komentáře (22)

Avatar
EweN
Člen
Avatar
EweN:28.12.2017 16:20

Děkuji za sepsání učebních materiálů, ale z posledních 2-3 cvičení nejsem moc moudrý. Nemáte někde další učební materiál? Poslední tři lekce jsem si procházel už nejméně 5x a stále nejsem schopnej dát dohromady kód bez přikukování do Vašich nápověd. (Funkci jako takovou jsem schopen dát dohromady , ale v momentě kdy se mi tam začne motat mb_strtoupper, atd.. jsem uplně v háji.
Popřípadě něco málo k cyklu FOR :

for($i= 1; $i<=10; $i++)
    echo('<td>' . ($i*$j) . '</td>');

Co která část vlastně dělá nebo ovlivňuje .. Mam v těhle věcech stále docela nejasno a nechci to psát jen jako hotovou věc.
Doufám, že teď nebudu před Váma vypadat jak hlupák a přeji hezký večer. =)

 
Odpovědět 28.12.2017 16:20
Avatar
Jaroslav Patrný:19. července 18:11

Ahoj, asi jsi to už vzhledem k době od tvého dotazu vyřešil, pokud ne, tak vnější podmínka kontroluje, zda v poli _POST něco je, to znamená jestli se odeslal formulář.

 
Odpovědět 19. července 18:11
Avatar
Libor Sitek
Člen
Avatar
Odpovídá na Jaroslav Patrný
Libor Sitek:19. července 19:16

Ahoj, co dělá ta první podmínka, to jsem pochopil, ale nevěděl jsem k čemu tam je, protože mě zajímá jen, zda byly odeslány data přes _POST s klíčem "zprava". Pokud nebyl odeslán formulář, tak tam takové data přece stejně nebudou a připadá mi zbytečné nejdříve kontrolovat, zda byly odeslány "nějaká data". A když už bych to chtěl třeba pro větší přehlednost kódu zkontrolovat, tak bych to určitě takhle nešťastně nezanořoval, ale použil bych

if ($_POST && isset($_POST['zprava']))
{
...
}

Výsledek je stejný a je to přehlednější...

Odpovědět 19. července 19:16
Když se chce, hledá se jak, když se nechce, hledá se proč
Avatar
Marek Uhlik
Člen
Avatar
Odpovídá na Libor Sitek
Marek Uhlik:19. července 21:12

hele nejsem phpkář , ale co když ti někdo spustí ten kód a ty data nebudou existovat ? Záleží na použití , ale může to vyhodit chybu a někdo to může třeba zneužít jako bezpečnostní díru.
Jestli se pletu tak mě někdo opravte.

 
Odpovědět 19. července 21:12
Avatar
IT Man
Redaktor
Avatar
Odpovídá na Libor Sitek
IT Man:19. července 21:53

Ahoj,
ano, skutečně jde o to samé. Ono je možné, že tam předtím bylo něco jiného a jak se to editovalo, zůstalo to v takovéto podobě. :)

Odpovědět 19. července 21:53
Cokoliv a kdokoliv může jednou uspět.
Avatar
Libor Sitek
Člen
Avatar
Odpovídá na Marek Uhlik
Libor Sitek:20. července 13:49

K tomu právě slouží funkce isset($var), která kontroluje, zda daná data existují, aby to nevyhazovalo chybu :-D
Navíc pokud by náhodou neexistovala proměnná $_POST, už první podmínka by vyhodila minimálně "Notice: Undefined variable". Ale to by se v PHP stát nemělo, protože $_POST je tzv. superglobální proměnná, která existuje vždy a obsahuje prázdné pole nebo pole z daty odeslané metodou POST. Proto je zbytečné např. používat isset($_POST), protože tato funkce by vrátila vždy true ;-)

Odpovědět 20. července 13:49
Když se chce, hledá se jak, když se nechce, hledá se proč
Avatar
Marek Uhlik
Člen
Avatar
Odpovídá na Libor Sitek
Marek Uhlik:20. července 14:12

Jo já vím, promiň já špatně pochopil tvojí otázku.

 
Odpovědět 20. července 14:12
Avatar
Fero M
Člen
Avatar
Fero M:18. září 17:08

omlouvám se za blbý dotaz, ale mohl by mi někdo přesněji definovat tuto část:

$znak = mb_substr($text, $i, 1);
if (in_array($znak, $znaky))
$pocet++;

 
Odpovědět 18. září 17:08
Avatar
IT Man
Redaktor
Avatar
Odpovídá na Fero M
IT Man:18. září 17:22

Ahoj,

Jelikož chceme zjistit počet souhlásek, projdeme si předaný řetězec znak po znaku. To nám zajišťuje daný kus kódu.

  1. Nejdříve získáme další znak z řetězce. Jdeme znak po znaku, proto je také použit for v dané ukázce. Funkce mb_substr() ti vrací určitý počet znaků z nějakého textu a my chceme vrátit pouze jeden znak, který začíná na pozici $i (jde se od 0 jako v poli - index).
  2. Zjistíme, jestli je daný písmeno v našem poli $znaky. Zjednodušeně - jestli je daný znak samohláska či souhláska. :)
  3. Pokud se daný znak nachází v předem určitém poli, zvýšíme počet, který následně vrátíme - počet samohlásek/sou­hlásek.

Jinak pro vkládání kódu používej to tlačítko vedle smajlíků, kód se poté naformátuje, pokud bude ve značkách code. :P

Odpovědět 18. září 17:22
Cokoliv a kdokoliv může jednou uspět.
Avatar
Fero M
Člen
Avatar
Odpovídá na IT Man
Fero M:18. září 21:09

děkuji mockrát

 
Odpovědět  +1 18. září 21:09
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 10 zpráv z 32. Zobrazit vše