« 1 2 »
Autor Zpráva
byXick
Profil *
Ahoj, dělám košík, ale někde mám chybu a nemůžu ji najít. V místě, kde má vypisovat cenu ($celkovacena) vypisuje 11,- Kč0,- Kč.
Tady je kód:
        <a href="kosik.php">
        <div class="kosik">
          <?php
            require('kosik_update.php');
            $celkovacena=0;
            foreach($_SESSION["polozky_kosiku"] as $polozka_kosiku)
              {
              echo $celkovacena=($polozka_kosiku['cena']*$polozka_kosiku['kusy']).',- Kč';
              }
          ?>  
        </div>
        </a>

                <form method="post" action="kosik_update.php">
                <input type="number" name="kusy" class="ks" min="1" max="100" value="1">ks
                <input type="hidden" name="id" value="'.$obsah['id'].'">
                <input type="hidden" name="typ" value="pridat">
                <input type="hidden" name="vratitadresu" value="'.$aktualni_adresa.'">
                <input type="submit" class="koupit" value="Koupit">
                </form>
Tady je kosik_update.php
<?php
require('databaze/pripojeni.php');
session_start();
if(isset($_POST["typ"]) && $_POST["typ"]=='pridat' && $_POST["kusy"]>0)
    {
    $udaj=$pripoj->prepare('SELECT * FROM produkty WHERE id="'.$_POST['id'].'" LIMIT 1');
    $udaj->bind_param('s', $nova_polozka['id']);
    $udaj->execute();
    $udaj->bind_result($nazev, $cena);
    while($udaj->fetch())
      {
      $nova_polozka['nazev']=$nazev;
      $nova_polozka['cena']=$cena;
      $nova_polozka['kusy']=$_POST["kusy"];
      
      if(isset($_SESSION["polozky_kosiku"]))
        {
          if(isset($_SESSION["polozky_kosiku"][$nova_polozka['id']]))
            {
            unset($_SESSION["polozky_kosiku"][$nova_polozka['id']]);
            }
        }
      }
      $_SESSION["polozky_kosiku"][$nova_polozka['id']]=$nova_polozka;  
    } 

$vratitadresu = (isset($_POST["vratitadresu"]))?urldecode($_POST["vratitadresu"]):'';
header('Location:'.$vratitadresu);
?
mimochodec
Profil
V tom místě výpisu procházíš všechny položky a pro každou z nich vypíšeš cenu vynásobenou počtem kusů.
byXick
Profil *
v místě výpisu procházím všechny položky, kde je určité id a z nich vypíšu cenu vynásobenou počtem kusů, ne?
mimochodec
Profil
No já žádné filtrování "kde je určité id" nevidím, ale o to asi nejde. Myslím, že řešíš to, že se vypisují všechny položky, ty je nechceš vypsat, ale chceš každou tu dvojici vynásobit a ten výsledek přičíst k nějaké sumě, kterou vypíšeš až pod tím cyklem.
byXick
Profil *
filtrování je tu WHERE id="'.$_POST['id'].'"
všechny položky chci vypsat až do kosik.php (ale to taky nefunguje)
zatím chci do $celkovacena vypsat cenu vynásobenou počtem kusů
mimochodec
Profil
byXick:
zatím chci do $celkovacena vypsat cenu vynásobenou počtem kusů

Tak si znovu přečti #4. Cyklus je v pořádku, jen v jeho průběhu nevypisuj, ale ty dvojice počet a cenazakus vynásob a přičti k nějaké sumě, kterou vypíšeš po tím cyklem.
byXick
Profil *
aha: ok, už to ukazuje správně 11,- Kč
ale funkce košíku jako taková nafunguje
mimochodec
Profil
byXick:
ale funkce košíku jako taková nafunguje

To není moc konkrétní popis toho, co to má dělat a toho, co to dělá, že ne?
juriad
Profil
byXick:
Těch chyb je tam mraky, ale nejvážnější je asi to, že $nova_polozka['id'] nikde nenastavuješ.
Další problém je ten, že na 7. řádku nastavuješ parametr, který ale v dotazu neexistuje (v dotazu je id zadáno natvrdo).
Další je například ten, že session_start nevoláš na začátku stránky (před tím jsi už stihl vypsat například to <a href="kosik.php">).
byXick
Profil *
tak podle mě každý ví, co má dělat košík
momentálně ať kliknu na tlačítko koupit u jakéhokoliv produktu a zadám jakékoliv množství, tak $celkovacena ukazuje 11,- Kč, když si nechám vypsat $nazev, tak to vypíše Ovesné vločky, můžu vypsat hmotnost, dostupnost atd., ale vypisuje to pouze tento jeden produkt i když jsem klikl na koupit u jiného produktu
do kosik.php se nevypíše nic
kód kosik.php je tu:
<form method="post" action="kosik_update.php">
<table>
  <tr><th>Nazev</th></tr>
  <?php
    if(isset($_SESSION["polozky_kosiku"]))
      {
        $celkovacena = 0;
        foreach ($_SESSION['polozky_kosiku'] as $polozka_kosiku)
        {
            $nazev = $polozka_kosiku["nazev"];
            echo '<tr>';
            echo '<td>'.$nazev.'</td>';
            echo '</tr>';
        }
      }
  ?>
</table>
</form>
juriad
Profil
byXick:
Když ladíš skripty, vypiš si obsah session:
var_dump($_SESSION);

Také si zapni výpis chyb a varování.
byXick
Profil *
    $query = "SELECT nazev, cena, obrazek FROM produkty WHERE id={$id}";
    $stmt = $pripoj->prepare($query);
    $stmt->execute();
    while ($row=$stmt->fetch()){
        $nazev = $row['nazev'];
        $cena = $row['cena'];
        $obrazek = $row['obrazek'];
    }
prosím jak je potřeba kód upravit, aby se do jednotlivých proměnných správně vypsala data z databáze?
mimochodec
Profil
A teď se tam zapisuje co?
juriad
Profil
Výsledek fetche je boolean - povedlo se/nepovedlo se.
Chybí ti tam bind_result.

Čteš vůbec dokumentaci, nebo lepíš kusy kódů z nejrůznějších zdrojů? Postup v [#1] je skoro správně.
byXick
Profil *
fakt nevím, co s tím, zkouším všechno možný už dva dny, ale bez výsledku
dokumentaci jsem nenašel, proto hledám kódy a snažím se jim porozumět


což se mi nedaří
juriad
Profil
byXick:
Nenašel? Tak to tě vážně lituji. V [#14] jsem ti dal rovnou dva odkazy. A tady máš odkaz přímo na úvodní stránku, kde jsou zmíněné všechny funkce mysqli.

    $query = "SELECT nazev, cena, obrazek FROM produkty WHERE id=?";
    $stmt = $pripoj->prepare($query); # připravíme
    $stmt->bind_param('i', $id); # doplníme data
    $stmt->execute(); # spustíme
    $stmt->bind_result($nazev, $cena, $obrazek); # zaregistrujeme výstup
    if ($stmt->fetch()){ # načteme řádek (kdyby jich mohlo být více, použil by se while)
        # proměnné $nazev, $cena a $obrazek obsahují data z nalezeného řádku
    } else {
        # řádek se zadaným id nebyl nalezen
    }
Alphard
Profil
Ten kód je dost zmatečný. Vidím v něm určitou snahu používat prepare statements, ale proměnné stejně vkládáte neošetřené přímo do dotazu (zřejmě vůbec nevíte, co děláte). Správně to napsal až [#16] juriad. Podstatné je, že v dotazu na 1. řádku je jenom id=? a proměnná se naváže až na třetím řádku (čímž se automaticky escapuje, resp. v tomto případě se vynutí konverze na číslo). To vás chrání před sql injection.

Pokud ale dotazy sestavuejte stylem [#1] nebo [#12], je celý ten mechanismus zbytečně složitý a jednodušší je použít „tradiční“ kombinaci metody query() a fetch_assoc(), která vám bude asi bližší.

Opět doporučuji použít dibi, které zvládá parametrické dotazy a je jednodušší na použití.
byXick
Profil *
proč když mám:
$new_product['id'] = $_POST['id'];
$statement->bind_param('i', $new_product['id']);
tak mi to píše:
Fatal error: Call to a member function bind_param() on a non-object
juriad
Profil
Protože v $statement není to, co očekáváš.
byXick
Profil *
Alphard:
děkuji, vyzkouším, toto totiž opravdu vůbec nepobírám
byXick
Profil *
Tak jsem se k tomu konečně po dlouhé době zase dostal, ale zase jsem se zasekl hned na začátku (proto prosím teď nekoukejte na nezabezpečenost kódu atd. - vím o tom). Kód je tu:
<?php
session_start();
require('databaze/pripojeni.php');
$vysledek=mysqli_query($pripoj, 'select * from produkty where id='.$_POST['id']);
$produkt=mysqli_fetch_array($vysledek);
if(isset($_POST["typ"]) && $_POST["typ"]=='pridat')
  {
  $polozka['id']=$produkt['id'];
  $polozka['nazev']=$produkt['nazev'];
  $polozka['cena']=$produkt['cena'];
  $polozka['mnozstvi']=$_POST['mnozstvi'];
  $_SESSION['kosik'][]=$polozka;
  }
?>
<table border="1">
  <tr>
    <th>id</th>
    <th>nazev</th>
    <th>cena</th>
    <th>mnozstvi</th>
  </tr>
<?php
foreach ($_SESSION['kosik'] as $kosik)
  {
  echo '<tr>
          <td>'.$kosik['id'].'</td>
          <td>'.$kosik['nazev'].'</td>
          <td>'.$kosik['cena'].'</td>
          <td>'.$kosik['mnozstvi'].'</td>
       </tr>';
  }
?>
</table>
píše mi to Undefined index: id, nazev, cena, mnozstvi (při výpisu $kosik['id'], $kosik['nazev'], $kosik['cena'], $kosik['mnozstvi'])
kde mám prosím chybu?
Fisir
Profil
Reaguji na byXicka:
Místo mysqli_fetch_array() použij mysqli_fetch_assoc().

prosím teď nekoukejte na nezabezpečenost kódu atd. - vím o tom
To je špatně. Kód musí být bezpečný od začátku, pokud jej budeš „zabezpečovat“ později, vždycky něco přehlédneš.
juriad
Profil
Fisir:
To není ten důvod. mysqli_fetch_array plní oboje, jak číslené indexy, tak i jména sloupců.

byXick:
Co říká:
var_dump($_SESSION);
?

Vždy když, v proměnné není něco, co očekáváš, var_dumpni si ji.
byXick
Profil *
var_dumpnul jsem ji a bylo tam toho strašně moc, tak jsem vyčistil session přes session_unset(); a funguje to
byXick
Profil *
jak se dá nejlépe řešit množství jednotlivých položek v košíku?
napadá mě leda $_POST['mnozstvi'] pokaždé vložit do databáze (přičíst k původní hodnotě) a vyčíst z databáze
ale to mi nepřijde jako správné řešení
juriad
Profil
Ale vždyť to množství můžeš mít v té SESSION, ne?

Vytvoř si funkce:
- addProductIntoCart(id, amount) - vloží produkt do košíku, pokud už tam je, upraví jeho množství; pokud je množství nekladné, odstraní produkt
- removeProductFromCart(id) - odstraní produkt z košíku
- listProductsInCart() - vrátí pole idček produktů a jejich množství [id => množství]
- getProductAmountInCart(id) - vrátí množství, kolikrát je v košíku (lze používat jako test přitomnosti, protože 0 je falsy hodnota)
- emptyCart() - odstraní vše z košíku

Až budeš mít tyto funkce hotové, na SESSION['kosik'] už nikdy nebudeš sahat přímo, vždy budeš volat tyto funkce. Můžeš je dobře odladit samostatně bez ohledu na existenci zbytku aplikace. Košík nepotřebuje znát název a cenu, to si můžeš vždy dotáhnout dotazem, také je košiku docela jedno, že může obsahovat id produktu, který neexistuje.
juriad
Profil
<?php

function prepareCart() {
    if (! isset($_SESSION['cart'])) {
        $_SESSION['cart'] = array();
    }
}

function addProductIntoCart($id, $amount) {
    prepareCart();

    if ($amount <= 0) {
        removeProductFromCart($id);
    } else {
        $_SESSION['cart'][$id] = $amount;
    }
}

function removeProductFromCart($id) {
    prepareCart();

    unset($_SESSION['cart'][$id]);
}

function listProductsInCart() {
    prepareCart();

    return $_SESSION['cart'];
}

function getProductAmountInCart($id) {
    prepareCart();

    return isset($_SESSION['cart'][$id]) ? $_SESSION['cart'][$id] : 0;
}

function emptyCart() {
    unset($_SESSION['cart']);
    prepareCart();
}

// a použije se to takto:

removeProductFromCart(11);
addProductIntoCart(12, 3);
addProductIntoCart(13, 2);
addProductIntoCart(13, 1);
addProductIntoCart(12, 0);
addProductIntoCart(14, 8);
removeProductFromCart(14);
var_dump(listProductsInCart());
abc
Profil
function addProductIntoCart($id, $amount) {
    prepareCart();
 
    if ($amount <= 0) {
        removeProductFromCart($id);
    } else {
        $_SESSION['cart'][$id] = $amount; //možná lépe "+="?  
    }
}
juriad
Profil
abc:
Také jsem nad tím přemýšlel, ale přiřazení je univerzálnější, počet může zjistit tou funkcí getProductAmountInCart. Nebo možná přidat boolovský přepínač jako třetí nepovinný parametr funkce. Nebo změnu počtu vyčlenit do zvláštní funkce (což by asi bylo nejchytřejší):
function addProductIntoCart($id, $amount) {
    prepareCart();
    
    setProductAmountInCart($id, $amount + getProductAmountInCart($id));
}

function setProductAmountInCart($id, $amount) {
    prepareCart();
 
    if ($amount <= 0) {
        removeProductFromCart($id);
    } else {
        $_SESSION['cart'][$id] = $amount;
    }
}

Upraveno.
byXick
Profil *
děkuju moc, je to perfektní funguje to, akorát u tohoto konkrétního kódu to vypisuje Notice: Undefined offset: 12... to stejný pro 13 a 14
když tam nebylo to + (jak podotknul uživatel abc), tak se toto nezobrazovalo, ale kód nefungoval správně (množství se nesčítalo, ale přepisovalo)
« 1 2 »

Vaše odpověď

Mohlo by se hodit

Odkud se sem odkazuje


Prosím používejte diakritiku a interpunkci.

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