Autor Zpráva
AlastorM
Profil
Snažím se předělat web a to tak, že chci mít veškerý obsah uložený v Mysql. Momentálně mám v databázi uloženo již pár textů. Jediné, co mě zajímá, je váš názor a případně rada, jak vypsat obsah z databáze na web pomocí php. Vše sice funguje, ale nevím, zda moje řešení není zbytečně složité.

Zde je ukázka toho, jak tahám data z mysql - získání dat pro titulek webu. Odkaz v menu mám ve tvaru clanky.php?kat=clanky. tímto odkazem se dostanu na stránku s uvedeným kódem, kde je seznam článků. Odkaz na konkrétní článek je pak ve tvaru clanek.php?kat=clanky&id=nadpis-webu

<?php
require "skripty/config.php";
$id=$_GET["id"];
$kategorie=$_GET["kat"];
if($id==""){                                                // tímto testuji, zda je otevřen článek, tedy zda url obsahuje proměnou id, pokud ne, jsem na seznamu článků
    echo"<title>mujweb - Články</title>";
}else{
    $vypis = mysql_query("SELECT * from obsah WHERE `kategorie` = '$kategorie' and `id` = '$id' ") or die(mysql_error());
        while ($polozka = mysql_fetch_array($vypis))
echo "<title>mujweb - Články - ".$polozka["nadpis"]."</title>";                             // pokud je v url proměná id, je otevřen nějaký článek, který bude uveden v titulku
}

následující část kódu buď zobrazí seznam článků, nebo konkrétní článek

$vypis = mysql_query("SELECT * from obsah WHERE `kategorie` = '$kategorie' ") or die(mysql_error());
while ($polozka = mysql_fetch_array($vypis))
if($id==$polozka["id"]){                         //opět stejný princip jako u titulku web, pokud url obsahuje proměnou id, načte se skript, který již vypíše příslušný článek
include "include/clanek.php";
}elseif($id=="" and $kategorie=="clanky"){           //pokud proměná id neexistuje, ale jsem v kategorii s články, načte se skript, který vypíše seznam
include "include/seznam.php";
}
?>

tento kód se stará o vypsaní seznamu článků z mysql. Těchto souborů mám 6 pro 6 kategorií, jelikož nevím, jak vše dostat na jednu stránku, aby to fungovalo stejně.

<h1>Seznam článků</h1>
<?php
$vypis = mysql_query("SELECT * from obsah WHERE `kategorie` = '$kategorie' ") or die(mysql_error());
while ($polozka = mysql_fetch_array($vypis))
echo "<h2 class='nazev'><a href='clanky.php?kat=clanky&id=".$polozka["id"]."'>".$polozka["nadpis"]."</a></h2>
<p class='popis'>".$polozka["popis"]."</p>
<p class='detail'>Datum zveřejnění: <strong>".$polozka["cas"]."</strong> | Autor: <strong>".$polozka["autor"]."</strong></p>";
?>

Poslední soubor, který mám 4x, jelikož jedna kategorie má 3 části (podkategorie), se stará o vypsání konkrétního článku

<?php
$vypis = mysql_query("SELECT * from obsah WHERE `kategorie` = '$kategorie' and `id` = '$id' ") or die(mysql_error());
while ($polozka = mysql_fetch_array($vypis))
echo $polozka["text"]
?>

Rád bych věděl, zda je tento celý kód dobrý, nebo zda je zbytečně složitý. Kromě tohoto mám ještě soubor index.php, kde tahám obsah pro 4 kategorie, podle toho, jak vypadá url - tedy index.php?kat=uvod načte jiný obsah pomocí include než index.php?kat=stranka2 nebo index.php?kat=stranka3. Živá ukázka teď na webu není, takže doufám,že lze princip fungování pochopit. je to poprvé, co něco podobného tvořím
peta
Profil
Neni to moc bezpecne.
http://cs.wikipedia.org/wiki/SQL_injection
$kategorie=$_GET["kat"];
"SELECT * from obsah WHERE `kategorie` = '$kategorie' "
Zkus si schvalne zapsat ted adresu stranky jako
stranka.php?kategorie=%27+OR+1%3d1

Pro sql prikazy bych si udelal vlastni funkci, ktere pak na jednom miste nastavis, jestli se maji zobrazovat sql errory nebo ma udelat die() a pod. Takhle to musis na kazdem radku opisovat a muzes udelat preklep.

Pokud nemas zapnute ob_flush, pak echo provadej co nejmene. Idealni stav je naplnit promenne nahore a pak mas dole samotny html kod stranky, kam promenne vypises.
Tori
Profil
AlastorM:
Doplňuju petův příspěvek, že na escapování se používají nejčastěji funkce mysql_real_escape_string (řetězce) a intval nebo přetypování na celé číslo (pro čísla).

Jinak moc věcí (SQL dotazy, části kódu, zřejmě i celé skripty) se tam opakuje, to by nemělo.
- pokud má SQL dotaz vrátit jen jeden řádek (podle ID), je zbytečné číst data cyklem, stačí prostě $radek = mysql_fetch_*($vysledek);
- pokud potřebujete z DB jen nadpis, místo SELECT * použijte SELECT nadpis
- získání všech údajů k jednomu článku + získání seznamu článků podle kategorie bych dala do samostatných funkcí (ID článku/kategorie předáte jako parametr, funkce vrátí buď pole dat nebo null (pokud dostane špatné ID)). Opět kvůli omezení opakování.
- používejte jednotné odsazení v kódu, bude se lépe číst i vám. Používejte složené závorky u while (předejdete náhodné chybě + schopnější editory automaticky doplní odsazení).

Nepochopila jsem jednu věc: to máte pro každou kategorii samostatný skript (kat=clanky → clanky.php)? Pokud není potřeba pro každou kategorii jiné zpracování v PHP, ale vždy jen zobrazíte, co přijde z DB, je to taky něco navíc. Ale jestli se některé kategorie liší, tak je to ok. Jen potom je možná zbytečné psát např. "clanky" dvakrát (jméno skriptu + hodnota parametru kat).
AlastorM
Profil
Tori:
momentálně to je takto:

menu obsahuje 10 odkazů, z toho 4 odkazy jsou index.php?kat=název_kategorie, kde v souboru index.php se podle proměnné kat načte příslušný obsah. Zbylých 6 odkazů jsou clanky.php?kat=clanky , stranka2.php?kat=nazev_kategorie , stranka3.php?kat=nazev_kategorie až po stranka6.php?kat=nazev_kategorie - to je celkem 6 souborů. K těmto 6 kategoriím mám ve složce include 6 skriptů, které vypisují seznam článků a všech 6 souborů obsahuje vlastně toto - jediný rozdíl je odkaz na článek - vyznačeno:

<h1>Seznam článků</h1>
<?php
$vypis = mysql_query("SELECT * from obsah WHERE `kategorie` = '$kategorie' ") or die(mysql_error());
while ($polozka = mysql_fetch_array($vypis))
echo "<h2 class='nazev'><a href='clanky.php?kat=clanky&id=".$polozka["id"]."'>".$polozka["nadpis"]."</a></h2>
<p class='popis'>".$polozka["popis"]."</p>
<p class='detail'>Datum zveřejnění: <strong>".$polozka["cas"]."</strong> | Autor: <strong>".$polozka["autor"]."</strong></p>";
?>

osobně bych to chtěl ale mít vše v jednom souboru, například clanky.php, kde by pak bylo v menu pouze clanky.php?kat=nazev_1 až clanky.php?kat=nazev_6 a podle proměnné kat v url by se načítal jak titulek stránky, tak obsah z mysql, což právě teď zkouším vyřešit.
Tori
Profil
AlastorM:
Liší se skripty clanky.php vs. stranka[2-6].php jinak, než titulkem? (Jiné zobrazení, jiný typ obsahu.) - myslím ty hlavní skripty, nikoli ty ze složky include.
AlastorM
Profil
Tori:
jsou stejné až na titulek a obsah, který se ale tahá z mysql. Obsah je tahán právě podle proměnných kat=název_kategorie&id=id-clanku v url. Titulek určuji pouze podle kat=název_kategorie
Tori
Profil
AlastorM:
jsou stejné až na titulek a obsah
Tak potom je zbytečné mít x stejných skriptů (a s každou novou kategorií přidávat další skript), stačí používat jen index.php?kat=xxx&id=yyy. Ještě si rozhodněte, co se má zobrazit, když nebude vybraná žádná kategorie (seznam kategorií nebo některá jako výchozí). Pak si přidáte tři funkce - jedna načte z DB seznam kategorií, druhá seznam článků v zadané kategorii, třetí načte konkrétní jeden článek podle ID - a stačí to jen poskládat dohromady, ne? Titulek kategorie bych taky ukládala do DB.
AlastorM
Profil
udělal jsem pár úprav (nebylo mi jasné, jak vyřešit zobrazování titulku stránky, nakonec má tedy titulek uložen v databázi) - bohužel ale mám problém, že nefunguje jak zobrazení titulku tak ani seznamu a článku. Zkoušel jsem dvě varianty - jedna nefunguje vůbec a druhá funguje špatně.

Tento kód by měl zobrazovat titulek, ale nezobrazuje nic, přitom bych čekal, že tato varianta by měla být správná:

require "skripty/config.php";
if (!isset($_GET["id"])) {
 $id = "nic";
 } else {
 $id = $_GET["id"];
 }
if (!isset($_GET["kat"])) {
 $kategorie = "clanky";
 } else {
 $kategorie = $_GET["kat"];
 }
$vypis = mysql_query("SELECT * FROM obsah WHERE `kategorie` = '$kategorie' and `id` = '$id' ") or die(mysql_error());
    while ($polozka = mysql_fetch_array($vypis))
if($id=="nic"){
    echo"<title>mujweb - ".$polozka["titulek"]."</title>";
}else{
echo "<title>mujweb - ".$polozka["titulek"]." - ".$polozka["nadpis"]."</title>";
}

Tento kód zobrazuje titulek špatně:

require "skripty/config.php";
if (!isset($_GET["id"])) {
 $id = "nic";
 } else {
 $id = $_GET["id"];
 }
if (!isset($_GET["kat"])) {
 $kategorie = "clanky";
 } else {
 $kategorie = $_GET["kat"];
 }
$vypis = mysql_query("SELECT * FROM obsah WHERE `kategorie` = '$kategorie'  ") or die(mysql_error());
    while ($polozka = mysql_fetch_array($vypis))
if($id=="nic"){
    echo"<title>mujweb - ".$polozka["titulek"]."</title>";
}else{
echo "<title>mujweb - ".$polozka["titulek"]." - ".$polozka["nadpis"]."</title>";
}

Udělal bych to jinak, ale v tomto směru se teprve učím a učím se právě tím, že to vytvářím. Nešlo by nastínit, jak by měla funkce pro vypsání seznamu článků vypadat. Stačí nějaká malá nápověda, protože funkci jsem ještě nevytvářel
Tori
Profil
function clankyPodleKategorie($kategorie)  {
  $vysledek = mysql_query("SELECT * FROM `obsah` WHERE `kategorie` = '".mysql_real_escape_string($kategorie)."'");
  if (!$vysledek) {
    return null;
  }
  $clanky = array();
  for ($i = mysql_num_rows($vysledek); $i > 0; $i--) {
    $clanky[] = mysql_fetch_assoc($vysledek);
  }
  return $clanky;
}
Problém s titulkem je myslím v dotazu, v tom and `id` = '$id' - pokud není zadané ID, tak se v DB hledá id = 'nic'. Asi bych to udělala přibližně tak:
// hlavička stránky...

$chyba = false;
if (!empty($_GET['id'])) {
  // najdi článek podle ID ( => samostatná funkce)
  // a zobraz ho.
  // pokud článek s takovým ID neexistuje, nastav $chyba = true;

} elseif (empty($_GET['id']) || $chyba) {
  // (= buď ID článku chybí, nebo je špatné)
  // zjisti kategorii, nebo nastav výchozí hodnotu
  // najdi clanky z této kategorie
  // pokud nebyly nalezeny, můžete a) napsat "kategorie neexistuje", 
  //   b) zkusit hledat v kategorii "clanky" (= hodnota napevno ve skriptu, nikoli z $_GET)
  // zobraz seznam článků
}

// patička stránky...
AlastorM
Profil
Tori:
díky za radu, něco jsem z toho použil - ne vše, pouze část, ale funguje na 100%. Otázka je jak moc je to te efektivní, ale zatím je to funkční

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: