I am attempting to create a shopping basket using PHP, I can add items, clear the whole basket however I am stuck when trying to remove just one item from the basket. I try to send a GET variable into the URL and then decrease the quantity of the specified item based on it's ID. Although at the moment it doesn't seem to work and if I click multiple times the URL gets huge and the GET variables keep getting added to the end rather than changing the whole URL.
Here is my PHP
<?php if(isset($_SESSION["cart"])) {
foreach ($_SESSION["cart"] as $id => $value) {
$ids .= $id . ',';
$count += $value['quantity'];
$totalPrice += $value['price'];
}
$query = $database->find_item_db($ids);
foreach ($query as $single_query) {
$id = $single_query['Sweet_ID'];
echo $single_query['Description']; ?> x <?php echo $_SESSION['cart'][$id]['quantity'] . '<a href=' . $_SERVER['REQUEST_URI'] .'&idToRemove=' . $id . '&action=remove> Remove </a>' . '</br>';
} ?>
<h3>Currently <?php echo $count; ?> Items in the basket</h3>
<h4> Total Price £<?php echo $totalPrice; ?> </h4>
<?php
} else {
echo "Your cart is empty";
}
?>
<?php
session_start();
if ($_GET['action'] == "add") {
$idNumber=intval($_GET['id']);
if (isset($_SESSION['cart'][$idNumber])) {
$_SESSION['cart'][$idNumber]['quantity']++;
} else {
$sql = $database->display_single($idNumber);
$second_id = $sql[0]['Sweet_ID'];
$price = $sql[0]['Price'];
$_SESSION['cart'][$second_id]=array(
"quantity" => 1,
"price" => $price
);
}
} else if ($GET['action'] == 'remove') {
$idNumber=intval($_GET['idToRemove']);
$_SESSION['cart'][$idNumber]['quantity']--;
} else if ($_GET['action'] == 'clear') {
unset($_SESSION['cart']);
}
?>
Change this:
'<a href=' . $_SERVER['REQUEST_URI'] .'&idToRemove=' . $id . '&action=remove> Remove </a>'
into this:
' Remove '
as $_SERVER['REQUEST_URI'] already contains all the parameters that are currently present in the URL.
This will create a blank URL (pointing to the current page) with only the idToRemove and action parameters.
(And add double quotes, to keep the URL nicely contained within the href attribute)
The problem comes from your HTML code.
I think you have something like this in your PHP :
<form action="<?php echo $_SERVER['PHP_SELF'].'?'.$_SERVER['QUERY_STRING']?>"
And as you always (re)call the same HTML form, the previous posted GET vars a posted again and again ....
I've programmed a basket class based on session you can use it , any question ask me please
class basket {
function add($pid,$qty){
if(!isset($_SESSION['basket'])){
$_SESSION['basket']=array();
$_SESSION['basket'][0]['productid']=$pid;
$_SESSION['basket'][0]['qty']=$qty;
echo 'The product was successfully added';
}
else {
if($this->isexist($pid,$qty)){
echo 'The quantity was successfully updated';
}
else{
$m=$_SESSION['basket'];
$max=count($m);
$_SESSION['basket'][$max]['productid']=$pid;
$_SESSION['basket'][$max]['qty']=$qty;
echo 'The product was successfully added';
}
}
}
function isexist($pid,$qty) {
$m=$_SESSION['basket'];
$max=count($m);
for($i=0;$i<$max;$i++){
if($pid==$_SESSION['basket'][$i]['productid']){
$_SESSION['basket'][$i]['qty']=$qty;
return true;break;}
}
return false;}
function delete($pid){
$m=$_SESSION['basket'];
$max=count($m);
for($i=0;$i<$max;$i++){
if($pid==$_SESSION['basket'][$i]['productid']){
unset($_SESSION['basket'][$i]);
$_SESSION['basket']=array_values($_SESSION['basket']);
$_SESSION['basket'.'num']-=1;echo 'The product was successfully delete';
break;}
}
}
function modify($pid,$qty){
$m=$_SESSION['basket'];
$max=count($m);
if($qty>0){
for($i=0;$i<$max;$i++){
if($pid==$_SESSION['basket'][$i]['productid']){
$_SESSION['basket'][$i]['qty']=$qty;break;}
}
}
else $this->delete($pid);
}
function show_basket() {
$max=count($_SESSION['basket']);
for($i=0;$i<$max;$i++){
echo 'id=>'.$_SESSION['basket'][$i]['productid'].'qty=>'.$_SESSION['basket'][$i]['qty'];
}
}
}
Related
function that runs when i want to edit a client status.
// deletes (sets inactive) client
function setClientStatus($client) {
if ($_GET['action'] == "setinactive") {
//database functions
$sql = 'UPDATE clients SET active="0" WHERE id="'. $client .'"';
$result = query($sql);
confirmQuery($result);
//set message to user to display
$_SESSION['error'] = false;
$msgs[] = "Client was set to inactive and removed from the list!";
$_SESSION['userMsg'] = $msgs;
}
if ($_GET['action'] == "setactive") {
//database functions
$sql = 'UPDATE clients SET active="1" WHERE id="'. $client .'"';
$result = query($sql);
confirmQuery($result);
//set message to user to display
$_SESSION['error'] = false;
$msgs[] = "Client was successfully restored!";
$_SESSION['userMsg'] = $msgs;
}
//display clients page with changes made
redirect('?page=clients');
}
function that displays the message.
//function that shows message and styles accordingly
function message($msgs) {
if(!empty($msgs)) {
foreach ($_SESSION['userMsg'] as $msg) {
if ($_SESSION['error'] == false) {
echo '<div class="noError">'.$msg.'</div>';
} else {
echo '<div class="error">'.$msg.'</div>';
}
}
}
unset($_SESSION['userMsg']);
unset($_SESSION['error']);
echo "hello";
}
here is where i call it in my page....
div class="pageContainer">
<?php
//display messages
message($_SESSION['userMsg']);
?>
</div>
Now when everything is run and i select to edit and client status (or add client, edit client as they all have the same message section, just with different message) i can see the message displayed on the screen. i have a javascript script that will hid the message after 5 seconds, but it doesn't hide. after viewing the page source i notice that the section of code is not visible. again, i can see it clearly see the message that is suppose to be there "Client was set to inactive and removed from the list!" (or whatever message is set to display) but it is NOT show in the view source html.
pic of page loaded with message
here is the view source.....
<div class="pageContainer">
<div>
** updated **
this small example script renders the html, but my above script doesn't...
function setError() {
$error[] = "Password field is to short";
$_SESSION['userMsg'] = $error;
//return $_SESSION['msg'];
}
function message($errors){
if(!empty($errors)) {
foreach ($_SESSION['userMsg'] as $error) {
echo $error.'<br>';
}
}
unset($_SESSION['userMsg']);
}
If I get you right, you want to display $msgs, so why you iterate $_SESSION['userMsg'] ?
Probably the $_SESSION['userMsg'] is null or empty. If you want to display the $msgs just iterate it. And later add to session if really needed. In you code, you always unset the $_SESSION['userMsg'] in the end of function, probably it is always null then. I didn't see the $_SESSION['userMsg'] needed here :
//function that shows message and styles accordingly
function message($msgs) {
if(!empty($msgs)) {
foreach ($msgs as $msg) {
if ($_SESSION['error'] == false) {
echo '<div class="noError">'.$msg.'</div>';
} else {
echo '<div class="error">'.$msg.'</div>';
}
}
}
unset($_SESSION['error']);
echo "hello";
}
UPDATED
After reading your comments, this is related to javascript problem. You should add the id in <div> in order for it's works.
if ($_SESSION['error'] == false) {
echo '<div id="noError" class="noError">'.$msg.'</div>';
} else {
echo '<div id="error" class="error">'.$msg.'</div>';
}
I was wondering if it's possible to have an if statement within an echo.
I have if statement which works fine when echoing results through the a while loop... This is the statement:
<div><?php if ($row['image'] == '') {}
else {echo "<img src='data:image/jpeg;base64,".base64_encode($row['image'])."'>";} ?>
<?php if ($row['video'] == '') {}
else {echo "<iframe src={$row['video']}></iframe>";} ?></div>`
So basically it's either a video or an image which works fine but then I implemented an infinite scroll to my blog which echoes the data from the database through and if statement like so:
if ($results) {
while($obj = $results->fetch_object())
{
echo '
<div><h3>'.$obj->headline.'</h3> </div>
<div><img src='data:image/jpeg;base64,".base64_encode('.$obj->image.')."'></div>'
So I wondering if anyone knows if it's possible to transfer that if statement within this echo so that it display an image firstly and then knows whether one is present or when a video is present within the database.
Thanks in advance for any help.
PS: I'm very new to coding/php!
Of course. Just split up the echo into multiple statements:
while($row = $results->fetch_object()) {
echo '<div>';
if ($row['image'] == '') {
} else {
echo "<img src='data:image/jpeg;base64,".base64_encode($row['image'])."'>";
}
if ($row['video'] == '') {
} else {
echo "<iframe src={$row['video']}></iframe>";
}
echo '</div>';
}
Try this one.
//first initialize a variable as a string
$result="";
while($obj = $results->fetch_object()) {
$result.="<div>";
if (!empty($obj['image'])){
$result.="<img src='data:image/jpeg;base64,".base64_encode($obj['image'])."'>";
}
elseif (!empty($obj['video'])){
$result.="<iframe src={$obj['video']}></iframe>";
}else{
//show some notification or leave it
//echo 'not Found';
}
$result.="</div>";
}
//finally you need to print the result variable.
echo $result;
I'm making a mini shopping cart for my project. Im storing the number of items chosen by the user, I don't understand that when i add one to my session variable I always get this error on the first go
Undefined index: cart_1 in D:\wamp\www\MiniCart\cart.php on line 100
And when I add again or refresh the same page it works fine. Why could this error be coming up? I removed the +=1 from the statement and it worked fine, apparently there is no syntax error too.
Cart.php
<!DOCTYPE>
<html>
<head></head>
<body>
<?php
session_start();
//The page where to jump to after adding/editing cart.
$page = 'mini_cart_index.php';
$link = mysqli_connect("localhost","root","","cart");
if(mysqli_connect_errno())
{
echo "Error:".mysqli_connect_error();
echo "<br/>";
} else {
echo "Connected to SQL<br/>";
}
//==================================================
if(isset($_GET['add']))
{
$obt=$_GET['add'];
$quantity_limit = 'SELECT id,quantity FROM products WHERE id='.mysqli_real_escape_string($link,(int)$_GET['add']);
$quantity = mysqli_query($link,$quantity_limit);
while($quantity_row=mysqli_fetch_assoc($quantity))
{
if($quantity_row['quantity']!=$_SESSION['cart_'.$_GET['add']])
{
$_SESSION['cart_'.$_GET['add']]+='1';
}
}
/*
echo 'id='.$obt.' '.'next<br/>';
echo 'Now storing info into session variable and adding one<br/>';
echo $_SESSION['cart_'.$_GET['add']];
echo '<br/>';
echo 'info stored<br/>';
*/
}
//***************************************************
function products()
{
GLOBAL $link;
$get ="SELECT id,name,description,price FROM products
WHERE quantity > 0 ORDER by id ASC";
if($result=mysqli_query($link,$get))
{
echo "Data Selected to be displayed<br/>";
} else {
echo "Error:".mysqli_error($link);
}
if(mysqli_num_rows($result)==0)
{
echo "There are no products to display!<br/>";
} else {
while($get_row=mysqli_fetch_assoc($result))
{
echo '<hr/><br/>';
echo 'displaying data from database<br/>';
echo '==================================';
echo '<p>'.$get_row['name'].'<br/>'.
$get_row['description'].'<br/>'.
number_format($get_row['price'],2).
' Add'.'</p>';
echo '<hr/><br/>';
}
}
}
echo 'outside'.$_SESSION['cart_1'];
?>
</body>
</html>
Mini_cart_index.php
<?php require 'cart.php';?>
<!DOCTYPE>
<html>
<head>
</head>
<body>
<?php products() ?>
</body>
</html>
That code is filled with SQL injection vulnerabilities, you should use PDO and prepare your statements.
PHP is warning you because it has to read the current value and add to it, but the first time you try to access it doesn't exist.
You could suppress the warning with:
#$_SESSION['cart_'.$_GET['add']]+='1';
A better way to do it though would be checking if it exists first
$name = 'cart_'.$_GET['add'];
if(isset($_SESSION[$name]) {
$_SESSION[$name] = 1;
} else {
$_SESSION[$name] += 1;
}
The problem is caused by the fact that...
$var['abc'] += 1
...is the same as
$var['abc'] = $var['abc'] + 1
So if you've got a clean session and $var['abc'] doesn't exist, you're going to get a warning because you're trying to read a non-existant value in order to add 1 to it.
While it's true that 0 + 1 = 1
...what's actually happening here is undefined + 1 = 1 with a warning.
As other answers have mentioned - to fix the issue, you can explicitly check that the array index exists before trying to increment it.
I'd do that with the ternary operator like this:
$key = 'card_' . $_GET['add'];
$_SESSION[$key] = (isset($_SESSION[$key]) ? $_SESSION[$key] : 0) + 1;
This is effectively saying
$val = ($val if it exists, otherwise 0) + 1;
Change your if statement to check if it's empty too:
if (!isset($_SESSION['cart_'.$_GET['add']])) {
$_SESSION['cart_'.$_GET['add']] = 1;
} elseif ($quantity_row['quantity'] != $_SESSION['cart_'.$_GET['add']]) {
$_SESSION['cart_'.$_GET['add']] += 1;
}
Basically I want to add one last piece of validation, if nothing is selected on the items page then an error appears or the user is returned to another page.
When submit is selected the form action sends it to the confirm page and the below is executed which displays the items selected if there is 1 or more entered if ($partno == $varname & $qty > 0) but I dont no what to put in the else part to return an error or take the user back to the previous page.
<?php
$visitor = $_POST['visitor'];
echo "<p>" . 'Hello ' . "<b>" . $visitor . "</b> " . 'please confirm your purchase(s) below.' . "</p>";
if (!($data = file('items.txt'))) {
echo 'ERROR: Failed to open file! </body></html>';
exit;
}
$total = 0;
foreach ($_POST as $varname => $varvalue) {
$qty = $varvalue;
foreach ($data as $thedata) {
list($partno, $name, $description, $price, $image) = explode('|', $thedata);
if ($partno == $varname & $qty > 0) {
echo "<tr><td><img src='$image' width='50' height='50' alt='image'</td>
<td>$partno<input type='hidden' name='$partno' value=$partno></td><td>$name</td><td>£$price</td>
<td> $qty</td><td><input type='hidden' name='visitor' value=$visitor></td>
<td><input type='hidden' name='qty' value=$qty></td></tr>";
$total = $total + $price * $qty;
} else {
}
}
}
?>
You'd have something like this:
$errors = array();
foreach(...) {
if ($partno == $varname & $qty > 0) {
... code for "ok" stuff
} else {
$errors[] = "$partno is incorrect";
}
}
if (count($errors) > 0) {
die("Errors: " . implode($errors));
}
... proceed to "success" code ...
Basically, for every test that fails, you record a message. Once the loop exits, if there's any error messages, you display them and abort processing. If there's no errors, you proceed onwards with the rest of the code.
Why not use a try catch block?
try {
if (isset($_POST)) {
if (!$email) {
throw new Exception('email is not valid', 100);
}
// everything is good process the request
}
throw new Exception('Error!', 200);
} catch (Exception $e) {
if ($e->getCode == 200) {
// redirect
} else {
// do something else
}
}
throw an Exception in your If statement, then put your data in try/catch block, so it will catch an exception if error occured
Consider the following approach: both the form and the php code to do something with the form data are on the same page. If the form was posted, you'll first check if the form was ok, after that you'll do something with the submitted data. If the form was not valid, display an error message.
The advantage is: no die() in the middle of your code, no strange redirects, everything in one script.
// simplified code in example.php
<?php
// in this variable we'll save success/error messages to print it
$msg = "";
// run this php code if the form was submitted
if(isset($_POST['submit'])) {
// is the form valid?
if (strlen($_POST['username']) == 0) {
$msg = "Please enter a username";
}
else {
// all validation tests are passed, give the user a nice feedback
// do something with the data, e.g. save it to the db
$msg = "Your data was saved. Have a great day";
}
}
?>
<div class="msg"><?php print $msg; ?></div>
<form method="post">
<input type="text" name="username">
<input type="submit" name="submit" value="Submit">
</form>
I created an object, it's named carwash. I created a session and assigned that object for session, if I enter quantity then and press buy button, I have result (example 6):
Your shopping cart contains 6 items.
but when I enter nothing, I get:
Your shopping cart contains items.
How should I do? Thank you! Here is all my code:
index.php
PHP Code:
<?php
session_start();
require_once 'carwash.php';
if (isset($_SESSION['encoded_cartopass'])) {
// first let's get the variable from the session
$encoded_cartopass = $_SESSION['encoded_cartopass'];
// now let's unpack it
$cartopass = unserialize($encoded_cartopass);
// echo quantity
echo "Your shopping cart contains {$cartopass->getQuantity()} items. <br /><br />";
}
else {
echo "Your shopping cart contains 0 items. <br /><br />";
}
?>
<form action="process.php" method="post">
Quantity: <input type="text" name="quantity" id="quantity"/>
<input type="submit" value="Buy" name="submit" />
</form>
process.php
PHP Code:
<?php
require_once 'carwash.php';
if (isset($_POST['submit'])) {
if (!isset($_SESSION['encoded_cartopass'])) {
// construct and set quantity
$cartopass = new carwash();
$cartopass->setQuantity($_POST['quantity']);
// construct and encode session
session_register('encoded_cartopass');
$_SESSION['encoded_cartopass'] = serialize($cartopass);
}
else {
// if session is existing, decode it and
// increment quantity
$encoded_cartopass = $_SESSION['encoded_cartopass'];
$cartopass = unserialize($encoded_cartopass);
$cartopass->incrementQuantity($_POST['quantity']);
// encode class and assign to session and
// session is used pass to index.php
$_SESSION['encode_cartopass'] = serialize($cartopass);
}
}
echo "<script>window.location.href='index.php'</script>";
?>
carwash.php
PHP Code:
<?php
class carwash {
private $carmake;
private $caryear;
private $quantity;
public function getCarmake() {
return $this->carmake;
}
public function setCarmake($carmake) {
$this->carmake = $carmake;
}
public function getCaryear() {
return $this->caryear;
}
public function setCaryear($caryear) {
$this->caryear = $caryear;
}
public function getQuantity() {
return $this->quantity;
}
public function setQuantity($quantity) {
$this->quantity = $quantity;
}
public function incrementQuantity($quantity = '') {
if (empty($quantity)) {
$this->quantity++;
}
else {
$this->quantity += $quantity;
}
}
public function washcar() {
echo "scruba, dub, dub, scruba, dub, dub <br />";
echo "I'm feelling cleaner, Thank you!";
}
}
?>
EDITED: (Found out what the curly braces do...)
Either of the following should work:
echo "Your shopping cart contains ".($cartopass->getQuantity() ? $cartopass->getQuantity() : 0)." items. <br /><br />";
echo "Your shopping cart contains ", $cartopass->getQuantity() + 0, " items. <br /><br />";
There are two possible solutions -
Check if the value of session was "0" (even though "0" is false, $v = "0"; isset($v) will return true).
destroy the session if $_POST was "0".
change your index.php to -
<?php
session_start();
require_once 'carwash.php';
if (isset($_SESSION['encoded_cartopass']) && $_SESSION['encoded_cartopass']) {
// first let's get the variable from the session
$encoded_cartopass = $_SESSION['encoded_cartopass'];
// now let's unpack it
$cartopass = unserialize($encoded_cartopass);
// echo quantity
echo "Your shopping cart contains {$cartopass->getQuantity()} items. <br /><br />";
}
else {
echo "Your shopping cart contains 0 items. <br /><br />";
}
?>
or change your process.php to -
<?php
require_once 'carwash.php';
if (isset($_POST['submit']) && $_POST['quantity']) {
if (!isset($_SESSION['encoded_cartopass'])) {
// construct and set quantity
$cartopass = new carwash();
$cartopass->setQuantity($_POST['quantity']);
// construct and encode session
session_register('encoded_cartopass');
$_SESSION['encoded_cartopass'] = serialize($cartopass);
}
else {
// if session is existing, decode it and
// increment quantity
$encoded_cartopass = $_SESSION['encoded_cartopass'];
$cartopass = unserialize($encoded_cartopass);
$cartopass->incrementQuantity($_POST['quantity']);
// encode class and assign to session and
// session is used pass to index.php
$_SESSION['encode_cartopass'] = serialize($cartopass);
}
} else {
unset($_SESSION['cartopass']);
session_destroy();
}
echo "<script>window.location.href='index.php'</script>";
?>