Shopping cart Session Problem

Hi there. I am trying to create a simple DVD shopping cart using the latest
version of PHP on an Apache server and MySQL db. I can list all of the
titles from my db but want something that stores the fact that the user
wishes to purchase a particular DVD when they click on it.

I have just tried hacking a system which allows the user to select a radio
button and then selects an input button and this adds the dvdid to the
sessions variable. I also tried providing a link to a php processing page
which I wanted to contain the dvdid. I could get the link to work but it
didnt have a dvdid attached to it.

The session/radio button currently doesn't work but I have left what I
attempted in the code as there may be simple errors in it and may be clearer
as to what I am trying to achieve.

Any help would be great.

<?php
error_reporting(1); // suppress warning messages
session_start(); // Initialise session
session_register("trolleyContents"); // Register our variables
?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"DTD/xhtml1-transitional.dtd">

PHP MySQL Query Form




body { background:#eeeebb }
tr { background:#ddeeff }
th { background:#ccddee }
td { background:#eeffee }
.idx { background:#ccddcc; text-align:right }


James' DVDs

<?php
require 'mysql.php';

function printError($errorMesg) {
printf("<br /> %s

", $errorMesg);
}

if ( !($link=mysql_connect($host, $user, $passwd)) ) {
printError(sprintf("Error connecting to database from %s, by user %s",
$host, $user));
} else {
mysql_select_db($dbName);
$query = 'SELECT * FROM dvd';
if ( !($result = mysql_query($query,$link)) ) {
printError(sprintf("Error %s : %s", mysql_errno(), mysql_error()));
} else {
if ( $result == 0 ) {
echo "Error " . mysql_errno() . ":" . mysql_error();
} else {
echo "";
for ( $i = 0 ; $i < mysql_num_fields($result) ; $i++ ) {
echo " ";
}
echo "";
for ( $i = 0 ; $i < mysql_num_rows($result) ; $i++ ) {
echo "";
$row = mysql_fetch_row($result);
for ( $j = 0 ; $j < mysql_num_fields($result) ; $j++ ) {
echo "";

}
?>
">
<?PHP

echo "<td>
?>

<?php </td>";
echo " ";
}
echo "
Row" . mysql_field_name($result,$i) .
"
" . ($i + 1) . " " . $row[$j] . "
";
}
}
}
?>




<?php
if ((!$trolleyContents && !$choice) || $clear) {
$trolleyContents = "";
echo "<p>Trolley currently empty";
} else {
if ( $choice ) $trolleyContents = $trolleyContents . "$choice";
echo "

Trolley contains:

";
echo "
    $trolleyContents
";
}
?>




Comments

  • I must confess your code confused me slightly! If I may be so cheeky, I think this would be a better way of doing what you want (it's very basic, I just cobbled it together)... say you have a basic MySQL table containing the dvd_id, the price and the DVD's title:

    [code]
    <?php
    session_start ();

    require ('mysql.php');
    mysql_connect ($host, $user, $pass);
    mysql_select_db ($database);

    if (isset ($_POST['submit']))
    $_SESSION['trolley'][] = $_POST['id'];
    else if (isset ($_POST['clear']))
    unset ($_SESSION['trolley']);
    ?>



    PHP & MySQL



    <?php
    $getdvds_query = mysql_query ('SELECT * FROM dvd');

    if (mysql_num_rows ($getdvds_query))
    {
    for ($id = 0; $dvd[] = mysql_fetch_assoc ($getdvds_query); $id++)
    {
    echo "<tr>
    ";
    echo "{$dvd[$id][price]}
    ";
    echo "{$dvd[$id][title]}
    ";
    echo "
    ";
    echo "
    ";
    }
    }
    ?>



    <?php
    if (!empty ($_SESSION['trolley']))
    {
    echo 'Trolley contents:<br />';

    foreach ($_SESSION['trolley'] as $trolley_item)
    echo $dvd[$trolley_item]['title']."

    ";
    }
    else
    echo 'Trolley is empty!';
    ?>



    [/code]

    ...but to be honest, there are probably better ways to add stuff to a cart - maybe making each DVD title a link which will add one to the basket using $_GET and so forth... but then it ain't my site so I'll shut up now!
  • Emperor, thanks very much for your reply.

    What I have thought about doing is having a link which will say "Add to cart" and this link will indeed do that.

    Also, could you explain what the following code does exactly as I am a little unsure on the speicifcs:

    if (isset ($_POST['submit']))
    $_SESSION['trolley'][] = $_POST['id'];
    else if (isset ($_POST['clear']))
    unset ($_SESSION['trolley']);

    AND

    $dvd[$trolley_item]['title']

    I'm not sure where 'title' goes.
    Many thanks,
    James
  • [code] if (isset ($_POST['submit']))
    $_SESSION['trolley'][] = $_POST['id'];
    else if (isset ($_POST['clear']))
    unset ($_SESSION['trolley']);[/code]

    This will either add an item onto the end of the $_SESSION['basket'] array or empty the basket depending on which button the user pressed.

    As for $dvd[$trolley_item]['title'] - it's kind of a long story... as I said I sort of cobbled the script together so it probably doesn't work exactly as you want it. Basically, each time mysql_fetch_assoc pulls an array of columns from the database into an array (in this simple case, an array containing the keys 'price' and 'title'), this array is stored in $dvd, which ends up an array of arrays. $dvd is indexed numerically, starting from 0 as you'd expect, each index pointing to an array representing info about a DVD.

    When a user adds a DVD to the basket, just the numerical index from $dvd is added to the $_SESSION['basket'] array. This way, all you need to do to find out the price or title of the DVD is to provide $dvd with the a numerical index to the array of DVD info you want....

    ... if you see what I mean. To illustrate, say I have 4 DVDs in my collection then the $dvd array would look like this:
    [code]
    Array
    (
    [0] => Array
    (
    [price] => 9.99
    [title] => remains of the day
    )

    [1] => Array
    (
    [price] => 13.99
    [title] => solaris
    )

    [2] => Array
    (
    [price] => 12.99
    [title] => life is beautiful
    )

    [3] => Array
    (
    [price] => 7.79
    [title] => terminator 2
    )

    [4] =>
    )
    [/code]
    Yup, the last one's a blank which I hadn't noticed before, but that's easy enough to take care of :)

    Now, if I add Solaris and Terminator 2 to my trolley, then $_SESSION['trolley'] will look like this:
    [code]
    Array
    (
    [0] => 1
    [1] => 3
    )
    [/code]

    so to find out the title/price of a trolley item, say the second one, just use the value, ie 3, as an index to $dvd, like so: $dvd[3]['title'] or whatever.

    Hope that clears things up.
  • I think I understand all of that. Thanks very much for explaining. I've been working on my code a little bit. Just trying to make it look a little better but have come up against a couple of problems. It now has columns that give the field names from the db but when I add to or empty the basket, I get the following error:

    Error 1064 : You have an error in your SQL syntax near 'Resource id #2' at line 1

    although when I go back to the page, the item has been added. Emptying the basket doesn't work at all though.

    Also, Do you know how I could replace the radio buttons with a link that would say something like "Add to basket"?

    Here is my code if you still feel like helping(or anyone else)!:

    <?php
    session_start ();

    require ('mysql.php');
    mysql_connect ($host, $user, $passwd);
    mysql_select_db ($dbName);

    if (isset ($_POST['submit']))
    $_SESSION['trolley'][] = $_POST['id'];
    else if (isset ($_POST['clear']))
    unset ($_SESSION['trolley']);
    ?>



    PHP & MySQL



    <?php
    $getdvds_query = mysql_query ('SELECT title, duration, rel, descr, genre, stock, price FROM dvd');


    echo "<table bgcolor="ddeeff">";
    for ( $i = 0 ; $i < mysql_num_fields($getdvds_query) ; $i++ ) {
    echo " ";
    }

    if (mysql_num_rows ($getdvds_query))
    {
    for ($id = 0; $dvd[] = mysql_fetch_assoc ($getdvds_query); $id++)
    {
    echo "
    ";
    echo " ";
    echo " ";
    echo " ";
    echo " ";
    echo " ";
    echo " ";
    echo " ";


    echo " ";
    echo " ";
    }
    }
    ?>
    Row" . mysql_field_name($getdvds_query,$i) . "
    {$dvd[$id][title]}{$dvd[$id][duration]}{$dvd[$id][rel]}{$dvd[$id][descr]}{$dvd[$id][genre]}{$dvd[$id][stock]}{$dvd[$id][price]}



    <?php
    if (!empty ($_SESSION['trolley']))
    {
    echo 'Trolley contents:<br />';

    foreach ($_SESSION['trolley'] as $trolley_item)
    echo $dvd[$trolley_item]['title']."

    ";
    }
    else
    echo 'Trolley is empty!';
    ?>



  • I have fixed the adding to and emptying the cart problem. The page name in the script was wrong!

    Any help on adding links would be great though. I'm not sure what information I should add.
  • : I have fixed the adding to and emptying the cart problem. The page name in the script was wrong!
    :
    : Any help on adding links would be great though. I'm not sure what information I should add.
    :

    Basically you'd pass the info via the query string rather than POST, so you'd scrap the form. This means making the "clear trolley" option a link too. Instead of putting a radio button after each DVD, put a link like this:
    [code] echo "add to basket";[/code]
    You can then make "empty trolley" a link by adding something like this to the page: empty trolley or whatever you want. Then change the code block at the top of the page to this:
    [code]
    if (isset ($_GET['add']))
    $_SESSION['trolley'][] = $_GET['add'];
    else if ($_GET['op'] === 'clear')
    unset ($_SESSION['trolley']);
    [/code]
  • Thanks very much Emperor, I'm starting to get somewhere with this now.

    I have been trying to create some links that take the user to a select of DVD titles of a specific genre. So I will have links to each genre in my DB. However, I am unsure how to implement this although I believe my SQL statement is correct:

    select title, duration, rel, descr, genre, stock, price from dvd where genre LIKE '%$genre%'

    I am thinking that each anchor tag will contain the name of the genre in it and this will be passed onto the page to do some processing. I'm not sure what form this processing will take.

    I was wondering if you or anyone else could offer some advice.
    Many Thanks.
  • The easiest way would probably just to put the genre in the query string, so each link would look like this:
    [code]whatever[/code]
    Then use "SELECT blah WHERE genre='$_GET[genre]'"

    However the best way I'd suggest is to have a separate table containing the genres, with just a genre_id column and a description column. Then for each DVD entered into the dvd table you only need to enter the corresponding genre_id. This way you can automatically generate a list of genres for the links, and it makes it much easier all-round to add new genres. The page would then look something like this:
    [code]
    $getgenres_query = mysql_query ('SELECT * FROM genre');

    while ($genre = mysql_fetch_assoc ($getgenres_query))
    echo "$genre[description]";
    [/code]

    Then obviously all you'd have to do to list the DVDs of that genre would be to execute an SQL query like "SELECT blah WHERE genre_id=$_GET[genre_id]"

    Hope that helps!
  • Emperor, thanks again for your help.

    I have used the while loop you suggested and currently have the genre names appearing on screen from the genre table (I already had a genre table with fields genreid, name, descr).

    But I have a couple of problems with your suggested method as some DVDs (in fact, most) belong to more than one genre and I do not have a genreid in my DVD table, instead I have the genre name. Here is an example entry in the genre field of the DVD table:

    Adventure/Action/Family

    I'm just trying to work out a way to link the name field in the genre table to the name field in the DVD table. Maybe using the LIKE keyword will work.

    James


  • Emperor, I have tried using the following code but receive the following errors:

    Warning: mysql_num_fields(): supplied argument is not a valid MySQL result resource in /home/yj103/public_html/browse_search.php on line 33

    which refers to the following line:
    for ( $i = 0 ; $i < mysql_num_fields($getdvds_query) ; $i++ ) {

    and the sam error referring to this line:
    if (mysql_num_rows ($getdvds_query))
    which I guess is related to the first.

    I'm not sure about the syntax for this line:
    $getdvds_query = mysql_query ('SELECT * FROM dvd where genre LIKE $_GET[%$genrename%]');

    I am trying to place the genre name into the variable and use this to test the genre field in the DVD table.

    CODE:

    <?php
    session_start ();

    require ('mysql.php');
    mysql_connect ($host, $user, $passwd);
    mysql_select_db ($dbName);

    if (isset ($_GET['add']))
    $_SESSION['trolley'][] = $_GET['add'];
    else if ($_GET['op'] === 'clear')
    $_SESSION['trolley'] = "";
    ?>



    PHP & MySQL


    <?php

    $getgenres_query = mysql_query ('SELECT * FROM genre');

    while ($genre = mysql_fetch_assoc ($getgenres_query))
    echo "<a href="browse_search.php?genrename=$genre[name]">$genre[name]";

    echo "";

    $getdvds_query = mysql_query ('SELECT * FROM dvd where genre LIKE $_GET[%$genrename%]');

    echo "";
    for ( $i = 0 ; $i < mysql_num_fields($getdvds_query) ; $i++ ) {
    echo " ";
    }

    if (mysql_num_rows ($getdvds_query))
    {
    for ($id = 0; $dvd[] = mysql_fetch_assoc ($getdvds_query); $id++)
    {
    echo "
    ";
    echo " ";
    echo " ";
    echo " ";
    echo " ";
    echo " ";
    echo " ";
    echo " ";

    echo "";
    echo " ";
    }
    }

    ?>
    " . mysql_field_name($getdvds_query,$i) . "
    {$dvd[$id][title]}{$dvd[$id][duration]}{$dvd[$id][rel]}{$dvd[$id][descr]}{$dvd[$id][genre]}{$dvd[$id][stock]}{$dvd[$id][price]}add to basket
    empty trolley




    <?php
    if (!empty ($_SESSION['trolley']))
    {
    echo 'Trolley contents:<br />';

    foreach ($_SESSION['trolley'] as $trolley_item)
    echo $dvd[$trolley_item]['title']."
    ";
    }
    else
    echo 'Trolley is empty!';
    ?>



  • This is in reply to the next message, but I wasn't allowed to post it there because there are already too many! Basically, if you want to include a variable in a string you need double quotes. If you use single quotes then everything in the string is taken literally.

    This means that
    [code]$getdvds_query = mysql_query ('SELECT * FROM dvd where genre LIKE $_GET[%$genrename%]');[/code]
    will actually pass MySQL the literal characters $genrename whereas this
    [code]$getdvds_query = mysql_query ("SELECT * FROM dvd where genre LIKE $_GET[%$genrename%]");[/code]
    uses double quotes and PHP will parse it first, inserting the value of $genrename.

    Basically, using single quotes is more efficient when you only need literal strings, because PHP doesn't have to parse it for variables or escape characters.
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories