Jump to content

variable variables and other 90's stuff...


StevenOliver

Recommended Posts

I've been trying for days to get this simple 1990's code to work. It won't work. Now, I don't even want to get it to work, because it's crappy ugly 1990's code...

Is there an elegant way to accomplish this? (I just want to be able to manually override the default catalog prices as needed.)

<?php
//default catalog prices:
$sku = "123456";
$price = "5.99";
if(isset($_POST[$sku])) { // if form submitted, and
	if( ${$_POST[$sku]} != $price) { //...and I manually changed price
	$price = ${$_POST[$sku]}; //...then change price to what I input
	}
}
echo '<form name="form1" method="post" action="Crappy1990sCodePage.php">';
echo '<input type="text" name="'.$sku.'" value="'.$price.'">';
echo '<input type="text" name="'.$sku.'" value="'.$price.'">';// (same sku may be listed twice)
echo '<input type="submit" class="no_class_its_the_90s_remember">'
echo '</form>';
?>

Thank you 😀

Edited by StevenOliver
Link to comment
Share on other sites

whatever this code's purpose is, you should probably be using an array for the form field name, with the sku value as the array index.

so, what is the purpose of this? who uses it, what are the input(s), how many sets of inputs are there, what processing will be done using those inputs, and what is the desired result or output for some sample input data?

Link to comment
Share on other sites

mac_gyver,
I manually input a series of sku's into my form to retrieve default prices from mySQL database, using a foreach loop.
Doing so will result in a list of a dozen or so sku numbers with prices, e.g.
sku# 23455.....$5.00
sku# 11111.....$10.00
sku# 11111.....$10.00
sku# 875..........$4.00

While reviewing the displayed result in my browser, I may wish to manually change sku# 11111 to display $5.00 instead of the default $10.00.
And, I'd like to be able to do that by clicking on the "$10.00" and simply typing in $5.00, then hit "Submit" and voila!
Desired Result:
sku# 23455.....$5.00
sku# 11111.....$5.00
sku# 11111.....$5.00
sku# 875..........$4.00

p.s. found a new problem..... you can't echo a number, so I have to append a letter prefix "A" to each of the "name" values in my original post:
echo '<input type="text" name="A"'.$sku.'" value="'.$price.'">';
.... and now the code is really ugly.... there's got to be a modern way of doing this.

Edited by StevenOliver
Link to comment
Share on other sites

a variable can be used as a variable, hence, variable variable. However, $_POST[$sku] will return the value of the post, which is 5.99. I don't see a variable named 5.99 and neither does php. So ${$_POST[$sku]} is really supposed to represent $5.99. I am not sure but i don't think the full stop is a valid variable name anyway. Why not just compare post sku to price?

<?php
  $sku = "123456"; $price = "5.99";
  if (isset($_POST[$sku]) && $_POST[$sku] !== $price) {
      $price = $_POST[$sku]; echo '<br>' . $price;
  }
?>
  <form method="post">
      <input type="text" name="<?php echo $sku; ?>" value="<?php echo $price; ?>">
      <input type="submit">
  </form>

 

Link to comment
Share on other sites

No, just temporarily changing the prices.
An example scenario: I tell a customer the next time they come in I'll sell them a hammer at half price.

The customer brings a screwdriver, 3 hammers, a shovel, and a hoe to the counter. I then type in the SKU numbers and get this result:

sku# 23455.....$5.00
sku# 11111.....$10.00
sku# 11111.....$10.00
sku# 11111.....$10.00
sku# 875..........$9.00
sku# 301..........$7.00

I remember he gets hammers at half price.... so I manually change the "$10.00" to the "$5.00" before I print the customer's receipt, and then close the browser/delete all temporary variable for the next customer....etc.

 

 

Link to comment
Share on other sites

@jodunno, thank you. But if there are duplicates, only changing the last one will update all the sku's prices.

Here is the result of a mySQL foreach loop. The name and price values are dynamically generated ("select name,price from my_mysql_table...."😞

<input type="text" name="A3829'" value="5.00"> <BR>
<input type="text" name="A1444'" value="12.00"> <BR> // <-- manually changing this has no effect
<input type="text" name="A1444'" value="12.00"> <BR> // <-- manually changing this one correctly updates both duplicates
<input type="text" name="A9035'" value="3.00"> <BR>

So if I change the first $12.00 line to $5.00, the second duplicate line will revert my change when the form is posted. It only works if I change the final $12.00 line (then all those same sku numbers will be updated to my desired price).

PHP pseudocode would be:
If user updates value for a specific SKU {
update all items with same SKU to updated price;
}

 

 

 

 

Link to comment
Share on other sites

personally, i am a visual learner. I can't see the code, so i can only offer solutions based upon the pseudocode.

I think that you would be better off seeking duplicates and incrementing a quantity associated with the product sku. then you know that the customer has three of a particular item. price change will represent $5.00 x skuQuantity.

edit:

i see: you don't want a product * quantity receipt. So you want to list all three and the new price. In that case, why not loop through the prooducts for matches of the price change sku? then, you can change the price of all three.

Edited by jodunno
wrong answer
Link to comment
Share on other sites

see the following example code, using an array for the form field name,  on how to retrieve existing data, populate a form with it, then do whatever you want with the submitted form data -

<?php

// example of editing existing data, even if not saving the result, i.e. the U in CRUD

session_start();

// fake a logged in user
$_SESSION['user_id'] = 123;

// recursive trim call-back function
function _trim($val){
	if(is_array($val)){
		return array_map('_trim',$val);
	} else {
		return trim($val);
	}
}

// require 'pdo_connection.php';
// the pdo connection code should - set the error mode to exceptions, set emulated prepared queries to false, and set the default fetch mode to assoc


// if the user is not logged in, go elsewhere
if(!isset($_SESSION['user_id']))
{
	header("Location:index.php");
	exit;
}

// if the user must have a rank or 'edit' permission to access this page, query to get that information and test it here...

// at this point, the user has permission to access this page

$post = []; // array to hold a trimmed working copy of the form data
$errors = []; // array to hold error messages

// post method form processing
if($_SERVER['REQUEST_METHOD'] == 'POST')
{
	// input(s) - sku, an array with an sku as the index for each element and the submitted price as the element's value
	
	// trim all the input data at once
	$post = array_map('_trim',$_POST); // since some of the form fields are arrays, use a recursive trim call-back function here.
	
	// validate all the inputs here, storing error messages in the $errors array, using the field name as the array index...
	
	// in no errors, use the input data
	if(empty($errors))
	{
		// examine the submitted data
		echo '<pre>'; print_r($post); echo '</pre>';
		
		// loop over the submitted data
		foreach($post['sku'] as $sku=>$price)
		{
			// use each set of submitted $sku/$price for anything you want...
		}
	}
	
	// if no errors, success
	if(empty($errors))
	{
		// redirect to the exact same url of this page to cause a get request - PRG Post, Redirect, Get.
		//header("Refresh:0");
		//exit;
		// note: if you want to display a one-time success message, store it in a session variable, test, display, and clear that session variable in the html document
	}
}

// if there's no form data, get the initial data needed to populate the form fields
if(empty($post))
{
	$sql = "SELECT sku, price 
		FROM your_table
		ORDER BY sku";
		// if you have a WHERE term, add it to the sql statement, change this to be a prepared query, and supply an array of inputs to the ->execute() method call.
	/*
	$stmt = $pdo->query($sql);
	foreach($stmt as $row)
	{
		$post['sku'][$row['sku']] = $row['price'];
	}
	*/
	
	// fake some data for demo purposes
	$post['sku'][12134] = 10.00;
	$post['sku'][5567] = 5.99;
}

?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Edit/Update example</title>
</head>
<body>

<?php
// display any errors
if(!empty($errors))
{
	echo '<p?' . implode('<br>',$errors) . '</p>';
}


// display the form
if(empty($post['sku']))
{
	echo '<p>There is no data to edit.</p>';
}
else
{
?>
<form method="post">
<input type='submit'><br>
<?php
foreach($post['sku'] as $sku=>$price)
{
	$price = number_format($price,2);
	echo "<label>$sku: <input type='text' name='sku[$sku]' value='$price'></label><br>";
}
?>
</form>
<?php
}
?>
</body>
</html>

 

Link to comment
Share on other sites

.... now I have a dozen things to learn...

You have "$post = []
Is that the same as declaring it as an array like this: $post = array();

I see this alot: if($_SERVER['REQUEST_METHOD'] == 'POST') {
Is that always necessary? Doesn't the mere "if(isset($_POST["something"])) do the trick?

"Modern code" seems to have an excess of "if there's no problem here, check here for a problem"
if(empty($errors)

How do you know when to say if(empty($errors)) vs if($errors == NULL)

PDO...... (saving that for later this summer. I'm just now converting  (and figuring out how to convert) all my 90's mySQL to "oo" style mySQLi)

So upon cursory exam of your the html side of your code, it doesn't look like it provides for listing each duplicated sku discreetly..... it probably does, but I don't see it. I will have to run the code, and see which line of code does this. Probably the foreach($post['sku'] as $sku=>$price) part. I would probably stick a $post['sku']  = $userSubmittedPrice in there....

Okay thank you again! I'm going to run the code....

 

Link to comment
Share on other sites

a problem still exists which hasn't been addressed: you have two text inputs with the same name in your example above (A1444, 12.00). The first occurrence of A1444 is considered as a duplicate. This is why you can only change the last occurrence. This is also why a quantity would be a better method. one sku, one price, quantity.

furthermore, i don't recommend blindly looping over post data. I recommend looping over known data and checking isset post[known_data]. Imagine a form with a million inputs.

Link to comment
Share on other sites

jodunno, you're right.
Subsequent duplicate occurences of the <input name="dupe" value="dupe"> will "override" whatever I change in the first occurence.

In simple terms,  "only change the last of the duplicates..... don't change any of the first duplicates."

I wish I was smart enough to understand mac_gyver's array suggestion.... I think that's where the answer lies. I can't wrap my head around arrays.

 

 

 

Link to comment
Share on other sites

Hello StevenOliver,

i only have time to tinker with a quantity method but it should be helpful to you (i hope so.) The following code only handles changes to the price and factors quantity into the final output, ie, if you really want to print multiple items on the same receipt. Otherwise, you could just echo a quantity and use simple addition to reflect a sum price of quantities greater than 1.

<?php
  if ($_SERVER['REQUEST_METHOD'] == 'POST') {
      $products = array('3829' => '5.00','1444' => '12.00','9035' => '3.00');
      $updatedProducts = array(); $skuQuantities = array();
      foreach ($products as $sku => $price) {
          if (isset($_POST[$sku]) && $_POST[$sku] !== $price) {
              if (isset($_POST[$sku.'q']) && $_POST[$sku.'q'] > 1) { $skuQuantities[$sku] = $_POST[$sku.'q']; }
              $updatedProducts[$sku] = $_POST[$sku]; continue;
          }   $updatedProducts[$sku] = $price;
      }

      foreach ($updatedProducts as $sku => $price) {
            if (array_key_exists($sku, $skuQuantities)) {
              for ($i=1; $i <= $skuQuantities[$sku]; $i++) { echo $sku . ': ' . $price . ' ' . '<br>'; }
            } else { echo $sku . ': ' . $price . '<br>'; }
      } unset($products); unset($updatedProducts);
    exit;
  }
?>
  <form name="form1" method="post">
      <input type="text" name="3829" value="5.00">
      <input type="number" name="3829q" min="1" value="1"><br>
      <input type="text" name="1444" value="12.00">
      <input type="number" name="1444q" min="1" value="2"><br>
      <input type="text" name="9035" value="3.00">
      <input type="number" name="9035q" min="1" value="1">
      <input type="submit" class="no_class_its_the_90s_remember">
  </form>

you should be able to fill a products array from your database based upon form submission or some other method. Then you could implement code like my example to work out quantities. I really don't have time to develop something further for you but it's a start.

Best wishes.

Link to comment
Share on other sites

I FIGURED IT OUT!
JAVASCRIPT! Yep, Javascript.

Force the text values of ALL the Price Field to change before POST.

I'll give all the <input> rows the id's of the sku numbers, and then use the if (e.keyCode == 13)", to change all the price values of the matching sku rows to my desired price right before POST.

See? Take a big mess, simply add slop, and voila! All fixed. Real good.

There! Done! Next Project! 😷

Link to comment
Share on other sites

Please note, there's a massive difference between this:

2 hours ago, jodunno said:

<input type="text" name="1444" value="12.00">

and this:

4 hours ago, mac_gyver said:

echo "<label>$sku: <input type='text' name='sku[$sku]' value='$price'></label><br>";

It's not just that mac_gyver's is output from PHP. Set up your form to let you use arrays in it's processing and your life will be much easier. Jodunno's code is technically sufficient, but you're going to find yourself jumping through hoops to figure out what the $_POST key you're looking for is, whereas you can run a simple loop with mac_gyver's code.

Understand, I'm not bashing Jodunno's code, s/he was very clear that this was just example code written rather quickly - I just want to make sure the example isn't taken too literally.

Link to comment
Share on other sites

a hardcoded example versus php output is hardly a massive difference. exaggeration.  The forum is not a code my php for me forum. The hardcoded example was posted by StevenOliver and used by me. Simply change the form to factor php output.

<?php
  $products = array('3829' => '5.00','1444' => '12.00','9035' => '3.00');
  if ($_SERVER['REQUEST_METHOD'] == 'POST') {
      $updatedProducts = array(); $skuQuantities = array(); $total = 0;
      foreach ($products as $sku => $price) {
          if (isset($_POST[$sku.'q']) && $_POST[$sku.'q'] > 1) { $skuQuantities[$sku] = $_POST[$sku.'q']; }
          if (isset($_POST[$sku]) && $_POST[$sku] !== $price) {
              $updatedProducts[$sku] = $_POST[$sku]; continue;
          }   $updatedProducts[$sku] = $price;
      }
      foreach ($updatedProducts as $sku => $price) {
            if (array_key_exists($sku, $skuQuantities)) {
              for ($i=1; $i <= $skuQuantities[$sku]; $i++) { echo $sku . ': $' . $price . ' ' . '<br>'; $total += $price; }
            } else { echo $sku . ': $' . $price . '<br>'; $total += $price; }
      } echo 'Total: $' . $total . '.00'; unset($products); unset($updatedProducts); unset($skuQuantities);
    exit;
  }
?>
  <form name="form1" method="post"><?php foreach ($products as $sku => $price) { ?>
      <input type="text" name="<?php echo $sku; ?>" value="<?php echo $price; ?>">
      <input type="number" name="<?php echo $sku . 'q'; ?>" min="1" value="1"><br><?php } ?>
      <input type="submit" class="no_class_its_the_90s_remember">
  </form>

updated code now shows a total price and accepts an unaltered price for display. try the code in xampp. the original problem is solved. Once again, macgyver's post does not solve the problem because it offers no solution for a duplicate entry. In addition, one should not blindly loop over POST data. Stop telling people to do this.

Best wishes.

Link to comment
Share on other sites

5 hours ago, jodunno said:

In addition, one should not blindly loop over POST data. Stop telling people to do this.

<?php
if($_SERVER['REQUEST_METHOD'] == 'POST'){
  foreach($_POST['options'] as $option){
    doSomething($option);
  }
}
?>

<form method="post">
  <input type="text" name="options[]" value="First Option">
  <input type="text" name="options[]" value="Second Option">
  <input type="text" name="options[]" value="Third Option">
  <input type="text" name="options[]" value="Fourth Option">
  <submit>
</form>

This is a very common method of handling post input. It's also a lot easier and more efficient than trying to loop over every sku in the database and see if it's set in the $_POST array one by one.

Link to comment
Share on other sites

20 hours ago, StevenOliver said:

mac_gyver,
I manually input a series of sku's into my form to retrieve default prices from mySQL database, using a foreach loop.
Doing so will result in a list of a dozen or so sku numbers with prices, e.g.

whereever do you get loop through a db? StevenOliver mentioned manually entering input. furthermore, if you don't know how to pull selected data from a database, then you have some reading to do. I'm moving on from this nonevent.

Anyway, manually selected inputs will work well with the quick solution that i've posted. Meantime, adding number_format will also handle dollars and cents.

Best wishes.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.