Can't increment product's quantity in session object - php

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>";
?>

Related

PHP Array Size Loop

We need to create a program that lets the user input the array size, their name, and age (depending on the array size the user entered). After that, we need to display all the elements of the array.
This is my code, but I'm having a problem adding a new element for another user and displaying it.
<html>
<head>
<title> PHP Array </title>
</head>
<body>
<form method="post" action="example.php">
<h3> Please enter the your information: </h3>
Array Size: <input type="text" name="arraysize"/> <br/><br>
Name: <input type="text" name="name" /><br/><br/>
Age: <input type="text" name="age"/> <br/><br/>
<input type="submit" name="submit" value="Submit"/>
<input type="reset" name="cancel" value="Cancel"/><br/><br/>
<?php
if(isset($_POST['submit'])){
if((!empty($_POST['name'])) && (!empty($_POST['age'])) && (!empty($_POST['arraysize']))){
$info = array($_POST['arraysize'], $_POST['name'], $_POST['g6ave']);
$arraylength = count($info);
for ($i=0; $i<=$arraylength ; $i++) {
$name = $_POST['name'];
for ($j=1; $j<=$i; $j++){
echo "User's Name" .$i. ": " .$name. [$j] ."<br>";
$age = $_POST['age'];
for($k=0; $k<=$i; $k++){
echo "User's Age: " .$age. [$k] ."<br/>";
}
}
}
}
}
?>
</body>
</html>
One approach (of other possible approaches) below should give you the main ideas. I also commented the aim of the each script part.
Approach below assumes that you'll use same URL for all your form pages. (1st, 2nd and the success page)
I hope this helps.
session_start(); //Start new or resume existing session
if (isset($_SESSION['form_success']) && $_SESSION['form_success'] === true)
{
require 'success_page.php';
unset($_SESSION['form_success']); // don't needed anymore
return; //not to continue to execute the code
}
// decide the page from user
if (isset($_POST['page']))
{
$page = $_POST['page'];
}
else
{
// display the first form page for the 1st time
require 'first_page_form.php';
return; //not to continue to execute the code
}
// if the first page was submitted.
if ($page === 'first') // or a specific POST flag from 1st page
{
//verify data from first page
$warnings = [];
if (first_page_data_valid() === true)
{
require 'second_page_form.php';
return; //not to continue to execute the code
}
// populate $warnings during first_page_data_valid()
//if first page data are invalid
print_r($warnings);
require 'first_page_form.php'; //display again
return; //not to continue to execute the code
}
// if the second page was submitted.
if ($page === 'second') // or a specific POST flag from 2nd page
{
//verify data from second page
$warnings = [];
if (second_page_data_valid() === true) // populate $warnings during second_page_data_valid()
{
// do things. ex: DB operations.
if (db_actions_success() === true)
{
$_SESSION['form_success'] = true; // defined and set to true.
// PHP permanent URL redirection. usage of 301 is important.
// it clears POST content. Prevents F5/refresh.
header("Location: https://www.url.com/form.php", true, 301);
exit; // good/recommended to use after redirect
}
else
{
echo 'System down or I have a bug. Try again later.';
return; //not to continue to execute the code
}
}
//if second page data is invalid
print_r($warnings);
require 'second_page_form.php'; //display again
return; //not to continue to execute the code
}

Number Guessing game PHP not functoning

I am trying to write a php game that raises an random ($secretNumber) number between 1 and 100, prints it to the screen, prints a form with buttons for the user to select either 'higher' 'lower' or 'correct'. Upon a button press, the outside values are altered accordingly and the computer raises another random number between the lowest and highest values. This continues until the user select correct and the game resets.
I am using a session to ensure that the values don't reset each time a button is clicked.
My problem is that the $secretNumber resets a couple of times before the $_SESSION locks it in.
Also the $randomGuess doesn't seem to lock in before updating.
Any suggestions as to why this isn't working?
<?php session_start() ?>
<?php
$low = 1;
$high = 100;
//create a function to hold a random number, between 1 and 100 and save it
//to a session variable.
secretNumber();
function secretNumber(){ //********** secretNumber() **********
global $randomGuess;
if(!isset($_SESSION["secretNumber"])){
$secretNumber = rand(1,100);
$_SESSION['secretNumber'] = $secretNumber;
} else {
$secretNumber = $_SESSION["secretNumber"];
echo($_SESSION['secretNumber']);
}
echo 'Secret number is '.$secretNumber;
echo ' <br/> ';
} //********** end secretNumber() ***********
//create a function to create a random guess as to the value of the
//first random number
randomGuess();
function randomGuess() { //********** randomGuess() **********
global $randomGuess;
global $low;
global $high;
if (isset($_SESSION['low'])){
$low = $_SESSION['low'];
}
if (isset($_SESSION['high'])){
$high = $_SESSION['high'];
}
$randomGuess = round($high-(($high-$low)/2));
echo 'Random guess is '.$randomGuess;
echo "<br/>";
$_SESSION['randomGuess'] = $randomGuess;
} // ********** end randomGuess() **********
//create a function to provide a response as to whether the guess is low,
//high or correct, and adjust the limits of the random guess accordingly.
checkGuess();
function checkGuess() { // ********** checkGuess() **********
global $low;
global $high;
global $randomGuess;
// form to show a 'high' button, a 'low' button and a 'correct' button
// Correct button needs to reset $_SESSION["secretNumber"], and start
// process over.
print <<<HERE
<div>
<br/><br/><br/>
<form method = "post" action = "" style="width:35%;
padding-left:35%">
<fieldset>
<button type = "submit" value="high" name ="high">Too High</button> <br/><br/>
<button type = "submit" value="low" name = "low">Too Low</button> <br/><br/>
<button type = "submit" value="correct" name = "correct">Correct</button> <br/><br/>
</fieldset>
</form>
</div>
HERE;
if (isset($_POST['low'])) {
echo "low <br/>";
echo "randomGuess = ".$randomGuess. "<br/>";
unset($_SESSION["low"]);
$low = $randomGuess;
$_SESSION['low'] = $low;
unset($_SESSION["randomNumber"]);
}
if (isset($_POST['high'])){
echo "high <br/>";
echo "randomGuess = ".$randomGuess. "<br/>";
unset($_SESSION["high"]);
$high = $randomGuess;
$_SESSION['high'] = $high;
unset($_SESSION["randomNumber"]);
}
} // ********** end checkGuess() **********
if (isset($_POST['correct'])){
print <<<HERE
<h2>Yes I guessed the correct secret number. Your secret is out</h2>
HERE;
unset($_SESSION["secretNumber"]);// unset the random number as the guess was correct.
unset($_SESSION["high"]);
unset($_SESSION["low"]);
}//end if
echo "low =".$low."<br/>";
echo "high =".$high." <br/>";
?>
Try to check if $secretNumber is same as session.
var_dump($secretNumber);
if($secretNumber != $_SESSION["secretNumber"]) {
echo "Restart is here";
}
Test it after every function and then you can see what is problem.

Remove an item from shopping basket PHP

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'];
}
}
}

Why does this undefined error occur when storing the first number to a $_SESSION[] variable?

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;
}

Creating an error in an else

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>

Categories