Obsah lekce:
V PHP je kromě základních datových typů (celá čísla, desetinná čísla, logické hodnoty, textové řetězce a další) také datový typ pole. Pole si můžeme představit jako řadu proměnných (většinou stejného typu, i když to není podmínkou).
Vysvětleme si pole na příkladu. Máme frontu na oběd, do které přicházejí lidé. Nevíme, kolik lidí nakonec ve frontě bude, proto není možné vytvořit určitý počet proměnných, abychom mohli do nich ukládat jména lidí v řadě, nebo třeba jejich výběr oběda. Potřebujeme tedy využít datový typ, do kterého lze stále přidávat další a další proměnné bez nutnosti znát předem jejich počet a právě takovým datovým typem je pole.
Pole se používá pro veškeré seznamy, mohou simulovat slovníky, představovat kolekce prvků, a spoustu dalších věcí, protože samotné pole je velmi užitečný nástroj.
Každé pole má své prvky a každý prvek má svůj index (klíč) a svou hodnotu. Následující zdrojový kód vytvoří pole s názvem fronta a naplní jej hodnotami, což budou jména lidí ve frontě.
$fronta[1]="Petr";
$fronta[2]="Pavel";
$fronta[3]="Marie";
$fronta[4]="Eva";
$fronta[5]="David";
V poli je tedy uloženo 5 jmen, takže prvek s indexem 1 má hodnotu Petr a tak dále. Stejného výsledku dosáhneme daleko kratším kódem.
$fronta=Array(1=>"Petr", "Pavel", "Marie", "Eva", "David");
Druhý zápis začíná přiřazením textu Petr na 1. index, protože defaultně jsou v PHP pole číslována od 0 (pozor v Pascalu se pole čísluje od 1), proto je nutno sdělit, že chceme číslování od jiného čísla, v opačném případě se začne číslovat automaticky od nuly.
Pro první příklad vytvoření pole, které bude číslováno od 1, by tedy stačilo zadat:
$fronta[1]="Petr";
$fronta[]="Pavel";
$fronta[]="Marie";
$fronta[]="Eva";
$fronta[]="David";
Stejně tak není nutno postupovat v přiřazování hodnot postupně, pokud bychom přiřadili nyní libovolné jméno na prvek s indexem třeba 1000, zvětšilo by se pole, aby obsahovalo 1000 prvků a na daném indexu by bylo jméno uloženo. Položky mezi začátkem a tímto indexem by poté pravděpodobně obsahovaly nesmyslná data, protože nebyly inicializovány.
Indexy lze u polí ale také nahradit textem, což může být v některých případech výhodné (takové pole se poté nazývá asociativní, zatímco pole s číselnými indexy se nazývá indexované). Jako příklad můžeme uvést pole s vymyšleným nastavením konfigurace naší webové aplikace.
$config[5] = 15;
$config["max_users"] = 15;
Jistě vidíme, že první řádek nám neříká naprosto nic o takovém nastavení, zatímco z řádku druhého lze dobře poznat, co bylo nastaveno. Indexování pomocí textu by šlo také využít třeba u souboru s překlady, pokud by naše aplikace načítala texty z externího souboru – každý text by měl svůj textový index a hodnoty by se pro jednotlivé jazyky měnily.
Pole nejsou omezeny pouze na jeden rozměr, existují také dvourozměrné a vícerozměrné pole, ovšem jejich použití je třeba velmi zvážit, protože další rozměry rapidně zvyšují nároky na systémové zdroje (hlavně na operační paměť).
Příklad dvourozměrného pole:
$pole[0][1] = "nějaký text";
Typickým příkladem pro použití dvourozměrného pole by mohla být šachovnice nebo piškvorky. Pro průchod takového pole je poté třeba použít 2 vnořené for cykly.
Pole lze procházet třemi základními typy algoritmů. Pro příklady bude využito pole ze začátku kapitoly, které obsahuje jména strávníků ve frontě na obědy.
for ($i=1; $i<6; $i++){
echo $fronta [$i];
}
Cyklus jednoduše začíná první indexem v poli a vypíše prvních 5 záznamů, pro výpis jiného počtu samozřejmě můžeme upravit podmínku. Při každém průchodu bude vypsána hodnota prvku s daným indexem.
foreach($fronta as $stravnik){
echo $stravnik;
}
Cyklus foreach je obdobou cyklu for, ovšem není nutno zadávat jakékoli podmínky, budou vypsány všechny položky pole. Syntaxe v závorce za příkazem foreach je následující – jako první je uvedeno zdrojové pole, po něm slovo as a na konci je uvedena proměnná, do které bude aktuálně procházený prvek pole uložen, abychom s ním mohli pracovat.
Reset($fronta);
while (Current($fronta)){
echo “Index: ”. Key($fronta).”\n”;
echo “Hodnota: ”.Current($fronta).”\n”;
Next($fronta);
}
Dále lze u této metody průchodu pole použít funkce Prev(pole), Each(pole) a End(pole). Tento způsob je obtížnější a má určité nedokonalosti, můžete si jej ale nastudovat sami, pokud se vám zdá užitečný.
PHP disponuje poměrně velkým počtem funkcí pro práci s polem, některé z nich si ukážeme a vysvětlíme.
Funkce vrátí počet prvků v poli, lze ji proto použít do podmínky v cyklu for na výpis celého pole.
Funkce projde celé pole a na každý jeho prvek aplikuje funkci z druhého parametru.
function radka ($string) {
echo "$string\n";
}
$znamka = array ("výborný", "chvalitebný", "dobrý", "dostatečný", "nedostatečný");
array_walk ($znamka, radka);
Nejprve je v kódu definována funkce pro výpis textu (jednoduše vypíše proměnou z parametru), následně je definováno pole známek a v závěru je vypsáno pole z 1. parametru ($znamka) díky užití funkce (ta je brána z 2. parametru) na každý prvek tohoto pole.
Funkce jednoduše vypíše obsah pole do stránky v prohlížeči.
Funkce ověří, jestli se text (lze zadat přímo text, nebo proměnnou) nachází v poli. Pokud ano, vrátí hodnotu true, v opačném případě vrátí false.
Funkce náhodně promíchá prvky v poli. Tato operace se může hodit například v případě, že tvoříme galerii a chceme, aby uživatel pokaždé viděl na začátku jiné fotky, nebo pokud používáme slideshow a chceme, aby se pořadí prvků při každém načtení stránky měnilo.
Funkce vrátí pole, ve kterém budou prvky s hodnotami čísel mezi zadanými parametry min a max.
$cisla = range(1, 100);
Funkce seřadí pole podle abecedy, ovšem pozor na to, že české znaky nejsou většinou podporovány, proto může řazení českých slov dopadnout jakkoli (záleží na nastavení serveru, většinou jsou ale znaky začínající písmenem s háčkem či čárkou řazeny na konec). Většinou jsou ale data již seřazena z databáze, proto se tato funkce tak hojně nevyužívá.
kočka
pes
zebra
člověk
Dalších funkcí pro řazení je spousta, uvedeme si zde seznam funkcí, o kterých si můžete vyhledat podrobnosti: asort, rsort, arsort, ksort, usort, uasort, uksort.
Příkaz list se používá pro rozdělení pole do proměnných. Zde je nutné znát předem počet prvků v poli, abychom mohli funkci předat dostatek parametrů. Tuto funkci využijeme, pokud potřebujeme pole rozdělit do proměnných. Pole musí existovat, proměnné budou při provádění funkce vytvořeny.
list($jmeno, $prijmeni, $email, $pozice) = $zamestnanec;
list($id, $nazev, $cena) = $vyrobek;
Funkce dokáže rozdělit zadaný text v místech výskytu zadaného oddělovače (znaku) a jednotlivé části uloží jako prvky do pole. První parametr je znak, který má fungovat jako oddělovač a druhý parametr je text (může být zadán přímo, nebo jako proměnná).
$input = "Honza,David,Petr,Pavel";
$jmena = explode(",", $input);
Po provedení funkce bude tedy pole jmena naplněno jednotlivými jmény a čárky budou ignorovány (tvoří oddělovače).
Pravý opak explode, funkce, která z pole vytvoří jeden řetězec, jednotlivé prvky lze oddělit oddělovačem. První parametr je oddělovač (lze zadat i prázdný "", pokud nechceme ničím oddělovat), druhý parametr je pole, ze kterého se mají prvky načíst. Budou použity všechny prvky pole.
V následujícím příkladu napíšeme funkci, která ze zadaného textu odstraní diakritiku – takový algoritmus by se mohl například hodit pro ukládání dat do databáze, která má nastavené jiné než české znakové sady.
Samotné odstranění by šlo provést mnoha způsoby, nastíníme si 3 z nich a ten poslední, nejdokonalejší, si ukážeme.
Jednak by šlo použít konstrukci switch s odnožemi case a projít řetězec znak po znaku, přičemž bychom testovali každý znak na diakritiku pomocí odnoží case a nahrazovali nepřípustné znaky.
Další možností by bylo použít funkci str_replace, která dokáže nahradit část řetězce jinou částí řetězce, ovšem bylo by nutné takovou funkci volat mnohokrát.
Poslední možnost je použít funkci StrTr, která požaduje 3 vstupní parametry. První parametrem je proměnná s textem, který se bude měnit, druhým parametrem jsou vstupní znaky a třetím parametrem jsou výstupní znaky.
function BezDK($text)
{
return StrTr($text,"áčďěéëíľĺňóöřšťůúüýž","acdeeeillnoorstuuuyz");
}
Funkce pracuje tak, že v zadaném textu hledá postupně výskyty každého znaku z řetězce vstupních znaků, a pokud takový najde, vymění jej za znak z řetězce výstupních znaků (samozřejmě znak na odpovídající pozici v tomto řetězci).
Stačí si tedy dát pozor, abychom měli stejný počet znaků ve vstupním a výstupním řetězci, a celá funkce je hotová.
Napište s využitím funkce StrTr dvě funkce, které budou umět zašifrovat a následně dešifrovat text, který se jim zadá jako parametr. Názvy funkcí budou encrypt() a decrypt().
Algoritmus pro šifrování nebude složitý, bude se jednat o šifru, kdy se zrcadlí abeceda – místo písmena A bude vypsáno písmeno Z a tak dále. Diakritiku neberte v potaz, stejně jako jakékoli další znaky kromě písmen.
Druhý úkol bude těžší. Napište funkci replaceSecretWords($text), které se bude předávat jeden textový parametr, který funkce po úpravě zase vrátí. Funkce bude mít k dispozici pole tajných slov (to si vytvořte s libovolnými slovy – může se jednat například o slova týkající se utajovaného projektu) a úkolem funkce bude všechna tajná slova v textu, který jí byl předán, změnit za slovo TAJNÉ. Na konci funkce vrátí opravený text (nezapomeňme, že v textu byly mezery).
(Nápověda: použijte funkci explode a vnořené cykly foreach.)