Avatar billede riefart Seniormester
05. november 2013 - 16:45 Der er 10 kommentarer og
1 løsning

Valg af samme vare 2 gange i indkøbskurv

Hej alle I eksperter.
Jeg har fundet et script til en indkøbskurv, som fungerer fint.
Men jeg har et ønske til en ændring og ved ikke hvordan jeg realiserer det.
Jeg har brug for at kunne tilføje den samme vare flere gange, da den fåes i forskellige størrelser og farver. Disse valg skal foretages i selve indkøbskurven.
Jeg kan fint ændre så varen optages i kurven flere gange, men opdateringen af antal påvirker alle de varelinier, hvori varen indgår.
Nogle der kan hjælpe med dette???

Herunder relevante sider fra scriptet.

produkter.php:
<?php
    include("includes/db.php");
    include("includes/functions.php");
if(isset($_REQUEST['command']) && $_REQUEST['command']=='add' && $_REQUEST['productid']>0){
        $pid=$_REQUEST['productid'];
        addtocart($pid,1);
        header("location:kurv.php");
        exit();
    }
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" type="text/css" href="shopping.css" />
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>Produkter</title>
<script language="javascript">
    function addtocart(pid){
        document.form1.productid.value=pid;
        document.form1.command.value='add';
        document.form1.submit();
    }
</script>
</head>


<body>
<form name="form1">
    <input type="hidden" name="productid" />
    <input type="hidden" name="command" />
</form>
<div align="center">
    <h1>Produkter</h1>
    <table id="produkttabel">
        <?php
            $result=mysql_query("select * from products") or die("select * from products"."<br/><br/>".mysql_error());
            while($row=mysql_fetch_array($result)){
        ?>
        <tr>
            <td><img src="<?php echo $row['picture']?>" /></td>
            <td>      <b><?php echo $row['name']?></b><br />
                    <?php echo $row['description']?><br />
                    Pris:<big style="color:green">  kr. <?php echo $row['price']?></big><br /><br />
                    <input type="button" value="Læg i kurv" onclick="addtocart(<?php echo $row['serial']?>)" />
            </td>
        </tr>
        <tr><td colspan="2"><hr size="1" /></td>
        <?php } ?>
    </table>
</div>
</body>
</html>

kurv.php:
<?php
    include("includes/db.php");
    include("includes/functions.php");
if(isset($_REQUEST['command']) && $_REQUEST['command']=='delete' && $_REQUEST['pid']>0){

        remove_product($_REQUEST['pid']);
    }
    else if(isset($_REQUEST['command']) && $_REQUEST['command']=='clear'){
        unset($_SESSION['cart']);
    }
    else if(isset($_REQUEST['command']) && $_REQUEST['command']=='update'){
        $max=count($_SESSION['cart']);
        for($i=0;$i<$max;$i++){
            $pid=$_SESSION['cart'][$i]['productid'];
            $q=intval($_REQUEST['product'.$pid]);
            if($q>0 && $q<=999){
                $_SESSION['cart'][$i]['qty']=$q;
            }
            else{
                $msg='Nogle af produkterne er ikke opdateret! Antallet skal være mellem 1 og 999';
            }
        }
    }

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" type="text/css" href="shopping.css" />
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>Shopping Cart</title>
<script language="javascript">
    function del(pid){
        if(confirm('Er du sikker på, at du vil slette denne vare?')){
            document.form1.pid.value=pid;
            document.form1.command.value='delete';
            document.form1.submit();
        }
    }
    function clear_cart(){
        if(confirm('Dette vil tømme din kurv. Vil du fortsætte?')){
            document.form1.command.value='clear';
            document.form1.submit();
        }
    }
    function update_cart(){
        document.form1.command.value='update';
        document.form1.submit();
    }


</script>
</head>

<body>
<form name="form1" method="post">
<input type="hidden" name="pid" />
<input type="hidden" name="command" />
    <div id="tabel">
    <div id="flyt_tabel">
        <h1>Din indkøbskurv</h1>
    <input type="button" value="Fortsæt i shoppen" onclick="window.location='produkter.php'" />
    </div>
        <table id="tabel_style">
        <?php
            if(is_array($_SESSION['cart'])){
                echo '<tr style="font-weight:bold"><td>Varelinie</td><td>Navn</td><td>Pris</td><td>Antal</td><td>Beløb</td><td>Slet</td></tr>';
                $max=count($_SESSION['cart']);
                for($i=0;$i<$max;$i++){
                    $pid=$_SESSION['cart'][$i]['productid'];
                    $q=$_SESSION['cart'][$i]['qty'];
                    $pname=get_product_name($pid);
                    if($q==0) continue;
            ?>
                    <tr bgcolor="#FFFFFF"><td><?php echo $i+1?></td><td><?php echo $pname?></td>
                    <td>kr <?php echo get_price($pid)?></td>
                    <td><input type="text" title="Husk at klikke på 'Opdatèr kurven'" name="product<?php echo $pid?>" value="<?php echo $q ?>" maxlength="3" size="2" /></td>
                    <td>kr <?php echo get_price($pid)*$q?></td>
                    <td><a href="java script:del(<?php echo $pid?>)">Slet varen</a></td></tr>
            <?php                   
                }
            ?>
                <tr><td><b>Ordretotal kr: <?php echo get_order_total()?>,-</b></td><td colspan="5" align="right"><input type="button" value="Tøm kurven" onclick="clear_cart()"><input type="button" value="Opdatèr kurven" onclick="update_cart()"><input type="button" value="Bekræft ordre" onclick="window.location='fakturering.php'"></td></tr>
            <?php
            }
            else{
                echo "<tr bgColor='#FFFFFF'><td>Din indkøbskurv er tom!</td>";
            }
        ?>
        </table>
    </div>
</form>
</body>
</html>

og funktioner.php:
<?php
    function get_product_name($pid){
        $result=mysql_query("select name from products where serial=$pid") or die("select name from products where serial=$pid"."<br/><br/>".mysql_error());
        $row=mysql_fetch_array($result);
        return $row['name'];
    }
    function get_price($pid){
        $result=mysql_query("select price from products where serial=$pid") or die("select name from products where serial=$pid"."<br/><br/>".mysql_error());
        $row=mysql_fetch_array($result);
        return $row['price'];
    }
    function remove_product($pid){
        $pid=intval($pid);
        $max=count($_SESSION['cart']);
        for($i=0;$i<$max;$i++){
            if($pid==$_SESSION['cart'][$i]['productid']){
                unset($_SESSION['cart'][$i]);
                break;
            }
        }
        $_SESSION['cart']=array_values($_SESSION['cart']);
    }
    function get_order_total(){
        $max=count($_SESSION['cart']);
        $sum=0;
        for($i=0;$i<$max;$i++){
            $pid=$_SESSION['cart'][$i]['productid'];
            $q=$_SESSION['cart'][$i]['qty'];
            $price=get_price($pid);
            $sum+=$price*$q;
        }
        return $sum;
    }
    function addtocart($pid,$q){
        if($pid<1 or $q<1) return;
       
        if(is_array($_SESSION['cart'])){
            if(product_exists($pid)) return;
            $max=count($_SESSION['cart']);
            $_SESSION['cart'][$max]['productid']=$pid;
            $_SESSION['cart'][$max]['qty']=$q;
        }
        else{
            $_SESSION['cart']=array();
            $_SESSION['cart'][0]['productid']=$pid;
            $_SESSION['cart'][0]['qty']=$q;
        }
    }
    function product_exists($pid){
        $pid=intval($pid);
        $max=count($_SESSION['cart']);
        $flag=0;
        for($i=0;$i<$max;$i++){
            if($pid==$_SESSION['cart'][$i]['productid']){
                $flag=1;
                break;
            }
        }
        return $flag;
    }

?>
Avatar billede repox Seniormester
05. november 2013 - 17:31 #1
Det var da noget frygtelig kode :-\ og gammelt? Har du et link til det script du har fundet?
Avatar billede riefart Seniormester
05. november 2013 - 20:09 #2
Avatar billede repox Seniormester
05. november 2013 - 20:21 #3
Det er godt nok også mere end fire år gammel kode - det er fyldt med sikkerhedsmæssige fejl og kode som er ved ikke at være understøttet længere.

Er der nogen særlig årsag til du ikke bruger en færdig eCommerce løsning? Eller måske bare en mere opdateret kodebasen?
Avatar billede riefart Seniormester
05. november 2013 - 21:23 #4
Jeg er interesseret i den enkleste løsning, uden at skulle sætte mig ind i et stort og omfattende system, og fandt derfor scriptene bag dette brugbare.
Mht sikkerhedsmæssige fejl tænker du vil på at det ikke er mysqli, eller hvad? Hvilken del af koden er i øvrigt ved at blive udfaset?
Har du et forslag til et andet script. Jeg vil have det så enkelt som muligt, og gerne selv kunne forstå lidt af hvad der sker "bag ved".
Avatar billede riefart Seniormester
05. november 2013 - 21:41 #5
Skal måske lige præcisere at der alene er tale om en varekurv og ingen betalingsmulighed.
Da jeg er temmelig newbie, var det her en mulighed for mig, for at arbejde med sessions. Derfor dette script.
Avatar billede repox Seniormester
05. november 2013 - 22:16 #6
Ja, blandt andet er MySQL udvidelsen deprecated og understøttelse er under udfasning. MySQLi udvidelsen er væsentligt bedre og giver bedre kontrol, bedre integration med MySQL i sig selv og giver dig mulighed for prepared statements som tillader dig at skrive sikrere kode.

Udover det er brugen af $_REQUEST ilde set i dag, da det tillader brugergeneret input fra alle request metoder.

Hvis du skal forsimple det så meget som muligt for dig selv, vil jeg anbefale dig selv at skrive det.
Mine forslag til løsninger er muligvis for komplicerede til nybegyndere og involverer pakkehåndtering fra Composer og PHP frameworks.
Avatar billede riefart Seniormester
06. november 2013 - 18:30 #7
Der er slet ingen tvivl om at jeg ændrer databasesøgningen til mysqli. Lige nu kører kurven bare på min lokale server, og jeg skal nok lade være med at "injicere" mig selv.
Mente at $_REQUEST var en samlet måde at søge på både $_GET og $_POST. Men der tager jeg måske fejl. Kan i hvertfald ikke forstå hvorfor metoden skulle være ilde set i dag.

Har du i øvrigt et forslag til løsning af det stillede problem?
Avatar billede repox Seniormester
06. november 2013 - 18:51 #8
$_REQUEST er en skidt ting, fordi du ikke længere er herre over hvilket input du får.

Eksempelvis ville en POST formular kunne få overskrevet sit input vha. GET parametre. Brug de rigtige superglobale variabler til det rigtige formål.

Problemet ligger i dine funktioner addtocart() samt product_exists().

De kontrollerer alene på produktets ID og du kan derfor ikke differentere mellem et produkt ID og dets attributter.
Det korrekte ville være at medsende dem til funktionerne og kontrollere om produkt ID'et og attributterne eksisterer eller om linien skal oprettes.
Avatar billede riefart Seniormester
06. november 2013 - 20:42 #9
Bare for lige at forstå det: Hvis jeg har en method="POST" formular kan jeg vel sagtens "REQUESTE" den uden at risikere noget, såfremt overfører ved mysqli?
Har du et forslag til dette:
"Det korrekte ville være at medsende dem til funktionerne og kontrollere om produkt ID'et og attributterne eksisterer eller om linien skal oprettes".?
Avatar billede repox Seniormester
06. november 2013 - 21:04 #10
Nej.
Hvis du har en post-formular med et <select> element, vil jeg kunne overskrive dine default værdier i dit <select> element ved at lave en ?ditfeltnavn=min%20fiktive%20værdi når du bruger $_REQUEST. Brug $_POST når du vil have POST data, $_GET når du vil have GET parametre.

Jeg har mangle forslag - en simpel en ville være at lave en md5 hash af produkt id'et sammensat af produktets attributter. F.eks.:

addtocart($_GET['productid'], 
          $_GET['antal'],
          array(
            'farve' => $_GET['farve'],
            'stoerrelse' => $_GET['stoerrelse'],
          ));
...
// I add to cart, gør du så således
function addtocart($pid, $q, $attributes)
{

  $product = md5($pid . implode($attributes));
  if(!isset($_SESSION['cart'][$product]))
  {
    $_SESSION['cart'][$product]['productid'] = $pid;
    $_SESSION['cart'][$product]['attributes'] = $attributes;
    $_SESSION['cart'][$product]['qty'] = $q;
  }
  else
  {
    $_SESSION['cart'][$product]['qty'] = $q;
  }

  if( $_SESSION['cart'][$product]['qty'] == 0 )
  {
    unset($_SESSION['cart'][$product]);
  }
}


Så sparede man også lige to andre funktioner; product_exists() og remove_product().

Til gengæld skal get_order_total() også laves om:
function get_order_total()
{
  $sum = 0;
  foreach($_SESSION['cart'] as $line)
  {
    $sum += get_price($line['productid']) * $line['qty'];
  }
  return $sum;
}


Så blev funktionen pludselig også meget pænere.
Det er selvfølgelig vigtigt at funktionen get_price() håndterer det væsentligt bedre hvis produktet ikke eksisterer (eksempelvis).
Avatar billede riefart Seniormester
08. november 2013 - 18:56 #11
Tak for hjælpen, så kom jeg lidt videre.
Det var super.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester