Autor Zpráva
Ikki
Profil
Opět Vás zdravím přátelé.

Potřebuji pomoct s tímto malinkým kódem.
Není to nic "PROFI".

<?php
include "config.php";
mysql_connect($db_server, $db_user, $db_pass);
mysql_select_db($db_name);
$query = mysql_query("SELECT * FROM novinky WHERE zmazane='0' ORDER BY id DESC");
$rows = mysql_num_rows($query);

if($rows == 0) {

  echo "Dosiaľ neboli napísane žiadne novinky.";

} else {

while($novinka = mysql_fetch_array($query)) {?>

                                <!-- Post Item -->
                                <div class="post-item">
                                    <div class="row">
                                        <div class="col-md-4">
                                            <div class="img-hover">
                                               <?php echo"<img src='../".$novinka['obrazok']."' class='img-responsive''>";?>
                                               <div class="overlay"><a href="#">+</a></div>
                                            </div>
                                        </div>
                                        <div class="col-md-8">  
                                            <h4><a onclick="showSpoiler(this);"><?php echo"".$novinka['nazov'].""?></a></h4>                                                                                    
                                            <p class="data-info"><?php echo"".$novinka['pridane']." / Napsal: <i class='fa fa-user' title='Vedení Projektu ".$novinka['napisal']." ✗ ".$novinka['napisal']." Postnul novinku s ID #".$novinka['id']."'></i><a href='profile.php?id=".$novinka['napisal_id']."'>".$novinka['napisal']."</a>";?></p>
                                            <p><?php echo"".$novinka['text'].""?><br />   
<div class="spoiler">                                            
<script type="text/javascript">                           
function showSpoiler(obj)
    {
    var inner = obj.parentNode.getElementsByTagName("div")[0];
    if (inner.style.display == "none")                                                                                                                                                                                                               
        inner.style.display = "";
    else
        inner.style.display = "none";                            
    }
</script>  
                                            <a onclick="showSpoiler(this);">Přečíst více [+]</a></p>
                                                <div class="inner" style="display:none;"><?php echo"".$novinka['cely_text'].""?></div></div>
                                            <?php if($_SESSION['level'] == 3) {
                                            echo "<a onclick='urcite_k()' href='?akcia=zmazat_novinku&idnovinky=".$novinka['id']."&so=".$novinka['napisal']."&si=".$novinka['napisal_id']."'>Smazat [-]</a>";}?>                                            
                                        </div></div></div>
                                        <?}}
                                        if($_SESSION['level'] == 3) {
                                        if(isset($_GET['akcia']) == "zmazat_novinku") {
                                        mysql_query("UPDATE novinky SET zmazane='1' WHERE Id='".mysql_real_escape_string($_GET['idnovinky'])."'");
                                        echo "<meta http-equiv='refresh' content='0;url=/index.php'><br>";}}?>

Potřebuji tento kód dát do nějakého stránkování.
Jsou to klasické novinky s ID & Textem a potřebuji, aby se na index.php zobrazovali 3 novinky a takto na každé stránce.
Je to možné?
mimochodec
Profil
Přesně jak píšeš, není to nic "profi". Vlastně to je dost vhodná úloha pro někoho, kdo v php už trochu něco umí a s mysql začíná. V sql dotazu použij limit a v php si ošetříš vše potřebné.
Ikki
Profil
S MySQL nemám problém.
Spíše nejsem schopný do tohoto kódu vložit jakýkoli kód pro stránkování.
V případě, že zamíšu hodnotu limit, tak to vypíše pouze daný počet novinek, jenže potřebuji aby to vypisovali minimálně 5 stránek o 3-4 novinkách.

Ikki.
Lukáš66666
Profil
Ikki:
Zkus si najít třeba nějakou třídu na stránkování.
Ikki
Profil
Lukáš66666:
A jaká by to měla být? o.o
Promiň, ale asi jsem opravdu hlupák.
RastyAmateur
Profil
Ikki:
Vyzkoušel bych hledání pod "php stránkování". Když jsem to řešil já, pomohl mi hned ten první odkaz (alespoň myslím).

V případě, že zamíšu hodnotu limit, tak to vypíše pouze daný počet novinek, jenže potřebuji aby to vypisovali minimálně 5 stránek o 3-4 novinkách.
K tomu slouží OFFSET

Princip je v tom, že si zjistíš celkový počet příspěvků. Pak to vydělíš a zaokrouhlíš nahoru, čímž dostaneš počet stránek. Poté zadáváš do databáze něco ve smyslu LIMIT počet_článků OFFSET strana*počet_článků.

Ještě bych se rád zeptal (jsem totiž hodně zvědavý), v tom kódu na řádce 10 (a nejen tam) píšeš slovensky a tady na diskusi česky...? To je nějaká zakázka, či co?
Sitole
Profil
Ikki:
Vysvětlím to pro tupce, ale je dobře že se ptáš, aby jsi nevědomky nepřišel k celému kodu.
Předem varuji, že musíš ošetřit všechny vstupy. Toto je pouze jednoduchý náčrt funkce.

Takže. Na první stránce bude dotaz vypadat nějak takto "SELECT * FROM novinky limit 0, 15
(Stránky budou po 15 výsledcích)

Poté přidáš šipku, číslo na další stránku, které bude obsahovat GET s hodnotou "1".
Na další stránce si pomocí PHP vypočítáš následující
$limit_prvni_cislo = 15 (krát) $_GET["stranka"] // Získáš patnáct
$limit_druhe_cislo = 2 (krát) (15 (krát) $_GET["stranka"]); // Tak získáš 30 a tedy obsah druhé stránky

"SELECT * FROM novinky limit $limit_prvni_cislo, $limit_druhe_cislo"

Opět odkážeš na další stránkou s hodnotou GET "2" (jako druhá stránka). Tam bude prakticky ten stejný kod, který bude fungovat.
Ještě jednou opakuji, že se jedná o naprostý základ a musíš si pohlídat všechny vstupy a upravit dle svého konceptu. (-:
mimochodec
Profil
Já bych to pojal dost jinak.
V první řadě je potřeba si určit, jak má vypadat logika stránkování. Dejme tomu, že bych to chtěl takto: stránkování bude odkazovat stránky 1, 2, aktuální stránku, předposlední, poslední.
Takže za předpokladu, že bude hodně stránek:

1 2 10 24 25 - celkem je 25 stránek (po x novinkách), aktuálně jsem na stránce 10.
1 2 3 24 25 - celkem je 25 stránek (po x novinkách), aktuálně jsem na stránce 2.
1 2 23 24 25 - celkem je 25 stránek (po x novinkách), aktuálně jsem na stránce 24.

Toto pokryje všechny situace, kdy celkový počet novinek děleno počtem novinek na stránce je víc než 4. Potom je potřeba vymyslet a ošetřit chování v případech, kdy počet zobrazených čísel je menší než 5 a aktuální stránka je poblíž jednoho nebo druhého konce.

Těch pár číslíček (a jedno ztučnění) musí vyrobit nějaký skript na základě několika málo čísel:
- celkový počet novinek
- počet novinek na stránku
- aktuální číslo stránky nebo pořadové číslo novinky

A nakonec z toho dostaneš dvě vytoužená čísla pro LIMIT.

Nejspíš to nevypadá jednoduše, ale je to v podstatě primitivní matematika a několik ifů v php. Chce to tužku, papír a odmyslet si ty nesmysly z prvního příspěvku, které s tím nesouvisí.
Lonanek
Profil
Sitole:
$limit_prvni_cislo = 15 (krát) $_GET["stranka"] // Získáš patnáct
$limit_druhe_cislo = 2 (krát) (15 (krát) $_GET["stranka"]); // Tak získáš 30 a tedy obsah druhé stránky
>
"SELECT * FROM novinky limit $limit_prvni_cislo, $limit_druhe_cislo"
Neřekl bych, že je to správný výpočet a také dotaz.

Podle této logiky budou zobrazeny záznamy takto:
0, 15 -> první (resp. nultá) stránka s 16 záznamy (0-15)
15, 30 -> druhá stránka s 30 záznamy (15-44)
30, 60 -> třetí stránka s 60 záznamy (30-89)
45, 90 -> čtvrtá stránka s 90 záznamy (45-134)
...

Nezapomeňte na to, že první záznam má číslo 0!
Ikki
Profil
RastyAmateur:
Ahoj, ano je to na zakázku.
Vše jsem zvládl udělat, jen stránkování jsem nikdy nedělal a celkově vymyslet jeho logiku mi příjde nelogické :D


Vyřešil jsem to jednoduchým kódem + ošetření kompletní!.

Děkuji všem za rady! ;)
Tomáš123
Profil
Predpokladám, že nejde z databázy naraz získať počet vyhovujúcich položiek a zoznam položiek na stránku. Rieši sa to teda na dvakrát alebo sa vytiahnu všetky záznamy a usporadúvajú sa v PHP? Ťahať údaje dvakrát sa mi nepáči. Skúsil som si teda druhú možnosť:
$link = mysqli_connect("localhost", "root", "", "zoznam");

$vysledok = mysqli_query($link, "SELECT * FROM `tabulka`");
$pocet_zaznamov = mysqli_num_rows($vysledok);
$poloziek_na_stranku = 5;
$pocet_stranok = ceil($pocet_zaznamov/$poloziek_na_stranku);
$rezerva = 5; #aby sa nevytvarala ďalšia stránka, ak je iba o pár záznamov viac

$stranka = (isset($_GET['stranka']) ? intval($_GET['stranka']) : 1);
    
#validácia parametru
if($stranka > $pocet_stranok) $stranka = $pocet_stranok;
if($stranka < 0) $stranka = 1;

while($zaznam = mysqli_fetch_array($vysledok)) {
    if($pocet_zaznamov >= $poloziek_na_stranku + $rezerva) {
        #stránkovanie
        for($i = (($stranka > 1) ? ($stranka - 1) * $poloziek_na_stranku : 1); $i < (($stranka > 1) ? $stranka * $poloziek_na_stranku : $poloziek_na_stranku); $i++) {
            echo $zaznam['item'].", ".$zaznam['ID']."<br>"; #$zoznam[$i]?
        }
    }
    else {
        echo $zaznam['item'].", ".$zaznam['ID']."<br>";
    }
}
Avšak, na riadku 19 mám problém s výpisom. Ako vypísať iba i-té položky z celkového počtu záznamov?

Zaradil som to sem, lebo mám za to, že to spolu súvisí.

Ďakujem za odpoveď.
Keeehi
Profil
Tomáš123:
Predpokladám, že nejde z databázy naraz získať počet vyhovujúcich položiek a zoznam položiek na stránku.
Teoreticky by to bylo možné ale byla by to neskutečná prasárna. Normálně se to dělá nadvakrát.
Martin2
Profil *
Tomáš123:
Predpokladám, že nejde z databázy naraz získať počet vyhovujúcich položiek a zoznam položiek na stránku. Rieši sa to teda na dvakrát alebo sa vytiahnu všetky záznamy a usporadúvajú sa v PHP?

Řeší se to příkazem SQL_CALC_FOUND_ROWS v dotazu. Pak stačí jen získat hodnotu z funkce FOUND_ROWS(), která celkový počet vrátí.
Tomáš123
Profil
Keeehi, Martin2:
Ďakujem. Včera večer som našiel v dokumentácii funkciu mysqli_data_seek(), ktorá by, myslím, mohla fungovať (premiestnenie ukzateľa, výpis), ale dobré riešenie to takisto nie je.
Tomáš123
Profil
Vytvoril som funkčné riešenie stránkovania, pripomienky vítané:
<?php
    $link = mysqli_connect("localhost", "root", "", "zoznam");
    
    $poloziek_na_stranku = 10;
    $max_zobrazenych_stranok = 10;
    $rezerva = 5; #aby sa nevytvarala ďalšia stránka, ak je iba o pár záznamov viac
    $stranka = (isset($_GET['stranka']) ? intval($_GET['stranka']) : 1);
    
    $ukazatele = array("vypustka" => "<span>...</span>", "okraje" => (array("prva" => "Prvá", "posledna" => "Posledná")));
    $povolit_vypustku = TRUE;
    $ukazatelov = count($ukazatele, COUNT_RECURSIVE);
    
    $povolit_vypustku = (isset($ukazatele['vypustka']) AND $povolit_vypustku === TRUE ? TRUE : FALSE);
    $ukazatelov -= (($povolit_vypustku === TRUE) ?  0 : 2);
    
    $pocet_zaznamov = mysqli_num_rows(mysqli_query($link, "SELECT `ID` FROM `tabulka`"));
    $pocet_stranok = ceil($pocet_zaznamov/$poloziek_na_stranku);
    
    #validácia parametru
    if($stranka > $pocet_stranok) $stranka = $pocet_stranok;
    if($stranka < 1) $stranka = 1;
    
    $zoznam = mysqli_query($link, "SELECT * FROM `tabulka` LIMIT ".($stranka - 1) * $poloziek_na_stranku.", $poloziek_na_stranku");    
    
    while($zaznam = mysqli_fetch_array($zoznam)) {
        echo $zaznam['item'].", ".$zaznam['ID']."<br>";
    }
    
    #stránok musí byť neparný počet
    $max_zobrazenych_stranok = (($max_zobrazenych_stranok % 2 == 1) ? $max_zobrazenych_stranok : $max_zobrazenych_stranok - 1);
    
    #výpis odkazov
    #ak je stránok dostatočné množstvo...
    if($pocet_stranok > $max_zobrazenych_stranok) {
        echo "<a href=\"?stranka=1\">".(($stranka == 1) ? "<strong>".$ukazatele['okraje']['prva']."</strong>" : $ukazatele['okraje']['prva'])."</a>";
        #ošetrenie proti zobrazeniu odkazov na neexisujúce stránky
        if($stranka > ($ukazatelov / 2) + floor(($max_zobrazenych_stranok - ($ukazatelov / 2)) / 2) AND $stranka <= $pocet_stranok - ($ukazatelov / 2) - floor(($max_zobrazenych_stranok - ($ukazatelov / 2)) / 2)) {
            if($povolit_vypustku === TRUE) {
                echo $ukazatele['vypustka'];
            }
            #výpis predchádzajúcich, aktuálnej a nasledujúcich stránok tak, aby bol počet stránok stále nanajvýš rovný $max_zobrazenych_stran*/
            for($i = $stranka + ($ukazatelov / 2) - floor($max_zobrazenych_stranok / 2); $i <= $stranka - ($ukazatelov / 2) + floor($max_zobrazenych_stranok / 2); $i++) {
                echo "<a href=\"?stranka=$i\">".(($i == $stranka) ? "<strong>$i</strong>" : $i)."</a>"; #Aktuálna stránka bude zvýraznená
            }
            if($povolit_vypustku === TRUE) {
                echo $ukazatele['vypustka'];;
            }
        }
        #$stranka ukazuje dostatočne blízko ku jednému z koncov zoznamu
        else {
            #druhá polovica
            if($stranka > ($pocet_stranok / 2)) {
                if($povolit_vypustku === TRUE) {
                    echo $ukazatele['vypustka'];
                }
                for($i = $pocet_stranok - ($max_zobrazenych_stranok - ($ukazatelov / 2) - 1); $i < $pocet_stranok; $i++) {
                    echo "<a href=\"?stranka=$i\">".(($i == $stranka) ? "<strong>$i</strong>" : $i)."</a>";
                }
            }
            #prvá polovica
            else {
                for($i = 2; $i < $max_zobrazenych_stranok - (($ukazatelov / 2) - 1); $i++) {
                    echo "<a href=\"?stranka=$i\">".(($i == $stranka) ? "<strong>$i</strong>" : $i)."</a>";
                }
                if($povolit_vypustku === TRUE) {
                    echo $ukazatele['vypustka'];
                }
            }
        }
        echo "<a href=\"?stranka=$pocet_stranok\">".(($stranka == $pocet_stranok) ? "<strong>".$ukazatele['okraje']['posledna']."</strong>" : $ukazatele['okraje']['posledna'])."</a>";
    }
    #...inak sa všetky vypíšu
    else {
        for($i = 1; $i <= $pocet_stranok; $i++) {
            echo "<a href=\"?stranka=$i\">".(($i == $stranka) ? "<strong>$i</strong>" : $i)."</a>";
        }
    }
    
    mysqli_close($link);
?>

Nakoniec som nemohol použiť radu Martina2, lebo overené číslo stránky potrebujem do druhého dopytu do databázy a overovať potrebujem na základe celkového počtu záznamov (možno som mohol celkový počet dostať aj cez COUNT(), bez výberu, ale v SQL sa nevyznám).

Snáď som tam (na) nič nezabudol.
Martin2
Profil *
Tomáš123:
ale v SQL sa nevyznám
V PHP taky moc ne, co?

Nevím no, je to prasecký program. Stránkování se řeší tak jak jsem psal: SELECT SQL_CALC_FOUND_ROWS … LIMIT $stranka*$pocet_na_stranku, $pocet_na_stranku. Pak můžeš zavolat druhý dotaz SELECT FOUND_ROWS(), který ti prozradí, kolik výsledků by měl předchozí dotaz bez klauzule LIMIT.

Neexistence stránky se neřeší nijak – když někdo zavolá neexistující offset a výsledek prvního dotazu je tak prázdný, prostě vrátíš chybu 404.
mimochodec
Profil
Připadá mi to drobátko nepřehledné, ale jestli ti to vyhovuje, tak proč ne. Jen bych doporučil zjišťovat počet řádků v tabulce zjišťovat úsporněji:

    $q = "select COUNT(ID) from tabulka";
    $radku = mysql_result(mysql_query($q), 0);

Kromě toho bych to udělal jako funkci, které bych dal název tabulky, pak aktuální číslo stránky a ono by mi to vyplivlo celý kód.
$stranka = (isset($_GET['stranka']) ? intval($_GET['stranka']) : 1);
$w = strankovani ("vyrobky", $stranka);
echo $w;

Kromě zpřehlednění to přinese i úsporu v případě, že bys to číslování chtěl zobrazit nad i pod výpisem - napoprvé to vygeneruješ a dáš do nějaké proměnné, napodruhé jen vypíšeš z té proměnné.

Přece jen si neodpustím dotaz. Opravdu ti toto připadá přehlednější, než použít if?
$ukazatelov -= (($povolit_vypustku === TRUE) ?  0 : 2);
Tomáš123
Profil
Martin2:
V PHP taky moc ne, co?
Nijak extra, v tomto kóde som ale nenarazil na svoje limity znalostí PHP. Pomerne ťažko sa mi vymýšľali všetky tie podmienky, takže som sa približoval skôr limitom znalosti programovania. Limity prehľadnosti som trochu prekročil, uznávam, sám sa v tom nevyznám. Rozmýšľal som, že by bolo lepšie vypočítať si všetky potrebné hodnoty vopred s tým, že by som združil rovnaké časti a vytváral potrebné variácie z nich. Malo by to o pár riadkov viac, ale s okomentovaním by sme sa v tom snáď všetci vyznali. Chcel som to urobiť teoreticky, aby sa na začiatku kódu zapísali hodnoty a všetko sa z toho vypočítalo.

Nevím no, je to prasecký program.
Nemusíš to študovať. Iba by ma zaujímalo, či súdiš podľa prehľadnosti alebo funkčnosti. Ťažko by som presne popísal ako vnímam „prasecký“ kód, ale ak je kód iba neprehľadný, je neprehľadný. Môj je ešte (trochu) neefektívny. Úplný bordel to snáď nie je.

mimochodec:
Ďakujem za tvoj príspevok [#8]. Napísal si to tak, že sa mi vyslovene žiadalo skúsiť si to vytvoriť.

Kromě toho bych to udělal jako funkci
Áno, mal som to v pláne. Preto aj tá pomerná zložitosť. Do databázy by som sa ale nepripájal vo vnútri tejto funkcie. Asi by som vytvoril druhú a volal to nejako takto:
$vysledky = funkcia_na_sprostredkovanie($nejake_parametre); #vracia pole
strankovanie($stranka, $vysledky, $poloziek_na_stranku, $pocet_stranok, $max_zobrazenych_stranok [, $povolit_vypustku = TRUE [, $rezerva = 5]] );

Opravdu ti toto připadá přehlednější, než použít if?
Pôvodne som to nechcel takto skrátiť, ale prišlo mi neužitočné vypísať $ukazatelov dvakrát navyše. Rozdeliť to do podmienok mi nenapadlo; prešiel som hneď k tejto podobe. Príde mi to dosť prehľadné na to, aby som to neroztiahol :-).

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: