PHP okénko: Setřídění záznamů podle vlastního kritéria

Jakub Vrána 27. 6. 2005

Dnešní PHP okénko ukazuje, jak se dá na stránce zobrazit seznam výrobků, které si návštěvník stránek naposledy prohlížel. Správné využití MySQL funkce řešení dále zjednodušuje a zpřehledňuje.

Řekněme, že chceme uživateli na stránce elektronického obchodu zobrazit posledních pět výrobků, které si prohlížel. Pro uložení takovéto informace se ideálně hodí session proměnná:

<?php
// $id je ID právě prohlíženého záznamu
if (!isset($_SESSION["prohlednute"])) {
    $_SESSION["prohlednute"] = array(); // prvotní inicializace pole
} elseif (($pos = array_search($id, $_SESSION["prohlednute"])) !== false) { // $id už v poli je
    unset($_SESSION["prohlednute"][$pos]); // vyjmeme ho a později vložíme na konec
} else {
    unset($_SESSION["prohlednute"][4]); // zobrazovat pouze posledních 5 prohlédnutých výrobků
}
// na tomto místě bude výpis prohlédnutých záznamů
array_unshift($_SESSION["prohlednute"], $id); // uložíme aktuální zboží pro příští stránku
?> 

Výpis prohlednutých záznamů by byl triviální za předpokladu, že bychom zboží nechtěli řadit podle pořadí, ve kterém bylo prohlédnuto. Pokud ho tak ale řadit chceme, budeme se muset trochu snažit:

<?php
if ($_SESSION["prohlednute"]) {
    $vyrobky = array();
    $result = mysql_query("SELECT * FROM vyrobky WHERE id IN (" . implode(", ", $_SESSION["prohlednute"]) . ")");
    while ($row = mysql_fetch_assoc($result)) {
        $vyrobky[$row["id"]] = $row;
    }
    mysql_free_result($result);
    foreach ($_SESSION["prohlednute"] as $id) {
        // zobrazení záznamu $vyrobky[$id]
    }
}
?> 

Kód je ale neelegantní a náročný na paměť. Problém se dá mnohem elegantněji vyřešit s využitím MySQL funkce FIELD. Tato funkce přijímá seznam parametrů a vrací pořadí prvního z nich mezi ostatními. Např. FIELD(id, 2, 4, 6) tedy vrátí pro id=4 dvojku, protože 4 je mezi dalšími parametry na druhém místě. A to je přesně ta funkce, kterou potřebujeme – výsledek chceme setřídit podle pořadí id v poli  $_SESSION["prohlednute"].

<?php
if ($_SESSION["prohlednute"]) {
    $prohlednute_list = implode(", ", $_SESSION["prohlednute"]);
    $result = mysql_query("SELECT * FROM vyrobky WHERE id IN ($prohlednute_list) ORDER BY FIELD(id, $prohlednute_list)");
    while ($row = mysql_fetch_assoc($result)) {
        // zobrazení záznamu $row
    }
    mysql_free_result($result);
}
?> 

Třídění podle dynamického výrazu je ještě pomalejší než třídění podle neindexovaného sloupce, takže bychom se mu za normálních okolností měli vyhnout. Na tomto místě si ho ale můžeme dovolit, protože počet vrácených záznamů je pevně omezen.


Podobně laděné texty můžete najít i na autorově weblogu PHP triky.

Našli jste v článku chybu?
Podnikatel.cz: Eseróčko vs. živnost. Co vyhrává?

Eseróčko vs. živnost. Co vyhrává?

Měšec.cz: Cestujte bez starostí, získejte výhodné pojištění

Cestujte bez starostí, získejte výhodné pojištění

Měšec.cz: 100% hypotékám zvoní umíráček

100% hypotékám zvoní umíráček

DigiZone.cz: Krajské televize na okraji zájmu?

Krajské televize na okraji zájmu?

DigiZone.cz: ČT veze bronz z klání televizní grafiky

ČT veze bronz z klání televizní grafiky

Lupa.cz: Vydavatelé jsou v háji, ale neumí si to připustit

Vydavatelé jsou v háji, ale neumí si to připustit

Lupa.cz: Text umírá, na webu zbude jen video

Text umírá, na webu zbude jen video

DigiZone.cz: Kritické poznámky k DVB-T2

Kritické poznámky k DVB-T2

Vitalia.cz: Recepty: Ač bez lepku, chutnají všem

Recepty: Ač bez lepku, chutnají všem

Vitalia.cz: Máte chutě? Nejezděte do světa, ale do Dobřichovic

Máte chutě? Nejezděte do světa, ale do Dobřichovic

DigiZone.cz: Noxon iRadio 1 W bude za pár měsíců

Noxon iRadio 1 W bude za pár měsíců

DigiZone.cz: Satelitní Flix TV vyráží do boje

Satelitní Flix TV vyráží do boje

120na80.cz: Krémy, nebo spreje na opalování?

Krémy, nebo spreje na opalování?

Lupa.cz: Vzali věc, která fungovala, a přidali internet

Vzali věc, která fungovala, a přidali internet

DigiZone.cz: Náhrada za nevrácená zařízení?

Náhrada za nevrácená zařízení?

Vitalia.cz: Tohle kafe má být hit léta

Tohle kafe má být hit léta

Měšec.cz: Ceny PHM v Evropě. Finty na úspory

Ceny PHM v Evropě. Finty na úspory

Měšec.cz: Inspirujte se: kam investují čeští dolaroví milionáři?

Inspirujte se: kam investují čeští dolaroví milionáři?

DigiZone.cz: Klesající sledovanost USA filmů potřetí

Klesající sledovanost USA filmů potřetí

DigiZone.cz: Soud zakázal šíření TV Markíza v ČR

Soud zakázal šíření TV Markíza v ČR