Autor Zpráva
byXick
Profil *
Čau, potřeboval bych vědět, jak se řeší vytváření stránek jednotlivým produktům v e-shopu? Klasicky v e-shopu je několik tisíců až desetitisíců produktů a nové produkty stále přibývají. Asi se fyzicky nevytváří soubory stránek jednotlivých výrobků, že?
juriad
Profil
byXick:
Ne. Je to podobné jako třeba tady na diskusi. Také neexistuje 157459 stránek, existuje jediná (plus mínus). Všimni si, že v adrese máš otazník a za ním nějaké parametry. O všechno se ve skutečnosti stará index.php, kterému parametry říkají, co má zobrazit. Například action=vthread&forum=3&topic=164326 říká, že jde o výpis vlákna v kategorii číslo 3 s číslem 164326.

To jak vypadají adresy v eshopech záleží na tvůrci, lze je v podstatě libovolně upravit, ale ve výsledku z nich musí být poznat, co se má zobrazit. Adresy tady by šlo změnit třeba na: /vlakno/jak-neco-udelat/e-shop-vytvareni-stranek-produktum-v-databazi. Proč se to nedělá? Protože na podobě adres zas tak nezáleží, hlavní je aby se zůstali stejné (což už skoro 11 let jsou).
byXick
Profil *
a co je obsah toho actionu? sql dotaz?
juriad
Profil
byXick:
Ve zdejším případě je to řetězec. To, že se parametr jmenuje action je pouze náhoda, stejně dobře by se mohl jmenovat třeba co-mam-delat. Záleží jen na tvém skriptu, aby tomu porozuměl (je to jen otázka toho, co má čekat v poli $_GET).
Můžeš si všimnut, že action se tu používá pár:
- vthread
- vtopic
- search
- manual
- userinfo

Databázový dotaz s tím úplně nesouvisí, ten se odehrává někde hluboho uvnitř index.php (nebo v includnutých skriptech). A v žádném případě se nesmí SQL dotaz objevit v URL (co kdyby jej uživatel změnil, pak by mohl s databází dělat cokoli, třeba si místo příšpěvků vypsat jména, e-maily a hesla uživatelů).
byXick
Profil *
Snažím se to zprovoznit, ale nějak mi to nejde a nevím, kde je chyba.
adresový řádek vypadá takto: http://localhost/shop/index.php?produkt=1 ale požadovaný produkt se nezobrazuje - v místě, kde by měl být, je bílo
Tady je výtah z kódu:
index.php:
...
if(isset($_GET['produkt']))
  {
  $produkt=$_GET['produkt'];
    if(preg_match('/^[0-9]+$/',$produkt))
      {
      include('databaze/produkty.php');
      include('podstranky/produkt.php');
      }
  }
...
databaze/produkty.php:
<?php
  $pripoj=mysqli_connect('localhost','root','','produkty');
  $produktt=mysqli_query($pripoj, "select * from produkty where id='%$produkt%'");
  mysqli_close($pripoj);
?>
podstranky/produkt.php:
     <?php
      while($obsah=mysqli_fetch_array($produktt))
        {
          echo '<div class="produkt">
                  <img src="obrazky/'.$obsah['obrazek'].'.jpg">
                  <span class="nazev">'.$obsah['nazev'].', '.$obsah['hmotnost'].'g</span>';
                  if($obsah['puvodnicena']=="")
                    {
                    echo '<span class="sleva"><br></span>';
                    }
                  else
                    {
                    echo '<span class="sleva">'.$obsah['puvodnicena'].',- Kč</span>';
                    }
          echo '<span class="cena">'.$obsah['cena'].',- Kč</span>
                <div class="zobrazit">Zobrazit</div>
                </div>
               '; 
        }
     ?>
juriad
Profil
byXick:
1. místo toho regexu můžeš klidně použít prosté přetypování na číslo bez další kontroly (máš číslo, tedy žádná neplecha nehrozí; přinejhorším prostě takový produkt nebude existovat):
if (isset($_GET['produkt'])) {
  $produktId = (int) $_GET['produkt'];
  include ...
}

2. sice se snažíš oddělit dotaz a výpis, ale neděláš to dobře.
Vytvoření databázového spojení patří někam mnohem dřív (vytvoř si jedno hned na začátku skriptu a pak jej jen používej).
Databázové spojení neukončuj. Téměř nikdy to není potřeba. Ukončí se samo při ukončení skriptu.
Takže celý databaze/produkty.php můžeš zahodit a jeho funkcionalitu rozstrkat jinam.

3. Dotaz do databáze pomocí pokusu o wildcardy je hnus a stejně nefunguje (k tomu by byl potřeba operátor LIKE.
$produkty = mysqli_query($pripoj, "SELECT * FROM produkty WHERE id = " . $produktId);

4. Pojmenovávej proměnné rozumně.
Místo $produkt měj $produktId, místo $produktt měj $produkty, místo $obsah měj $produkt

5. Jelikož je spojení s databází aktivní (odstranil jsi to volání mysqli_close, že ano?), bude fungovat i ten cyklus. Jelikož ale máš podmínku na id, které je předpokládám klíčem, vždy dostaneš maximálně jeden záznam. Změň tedy while na if (while nevadí, ale toto jen lépe vystihne, že se jedná o jeden produkt). Zároveň ti if umožní mít else větev, ve které můžeš napsat, že produkt nebyl nalezen, aby uživatel nezíral na bílou stránku.

6. Při výpisu bys měl používat funkci htmlspecialchars, protože název obrázku, název produktu nebo další položky (až přibudou) mohou obsahovat špičaté závorky, ampersandy. Já vím, asi se to nestane, ale přece nechceš, aby se ti eshop rozbil i kdyby náhodou.

7. <div class="zobrazit"> by snad měl být odkaz, ne?

8. Při tvorbě eshopů jde o peníze. Stačí, aby pár zákazníkům nešlo odeslat objednávku, nedej bože, aby celý eshop šel do kytek. Provozovatel na tom tratí a ty máš pořádný průser. Předpokládám proto, že to je jen hračka, kterou nikde na webu nepoužiješ.

Abych to shrnul. Tvůj problém je nejspíš způsoben dvěma efekty:
1. pokládáš do databáze špatný dotaz (ta procentítka tam nemají co dělat)
2. databázové spojení zavřeš dříve než si stihneš vytáhnout výsledek dotazu.
byXick
Profil *
juriad:
já mám databázové spojení hned na začátku index.php, ale protože definuji proměnnou $produktid až podstatně hlouběji v index.php, tak jsem musel vytvořit nové připojení k databázi právě až po definování proměnné

děkuji moc za připomínky, opraveno a vše už funguje, akorát mám tedy dvě připojení k databázi

juriad:
7. <div class="zobrazit"> by snad měl být odkaz, ne?
jasně, to udělám později

8. Při tvorbě eshopů jde o peníze. Stačí, aby pár zákazníkům nešlo odeslat objednávku, nedej bože, aby celý eshop šel do kytek. Provozovatel na tom tratí a ty máš pořádný průser. Předpokládám proto, že to je jen hračka, kterou nikde na webu nepoužiješ.
to je mi jasný, zatím je web v plenkách


ajo, tak nemusím mít dvoje připojení, díky tomu, že jsem vyhodil to mysqli_close, tak stačí dát dotaz do podstranky/produkt.php a je to v pohodě
takže super, děkuju, vyřešeno
juriad
Profil
byXick:
Měj pouze jediné připojení. Pamatuj na to, že všechny proměnné vytvořené dříve (před includem) stále existují. Pokud ji potřebuješ použít uvnitř funkce, předej si ji jako parametr.
Jak závisí definice $produktId na $spojeni? $poduktId potřebuješ přece až při dotazu, nikoli při připojení k databázi.
byXick
Profil *
juriad:
já jsem měl doteď všechny dotazy právě v tom spojení
věděl jsem, že to je blbost, protože všechny ty dotazy se vykonávají při spojení, ale jelikož jsem tam měl to mysqli_close, tak mi dotazy jinde nefungovaly
měl jsem za to, že to mysqli_close tam musí být
teď tedy dám jednotlivé dotazy na správná místa

Vaše odpověď


Prosím používejte diakritiku a interpunkci.

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