homepage Welcome to WebmasterWorld Guest from 54.197.110.151
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Pubcon Platinum Sponsor 2014
Home / Forums Index / Code, Content, and Presentation / PHP Server Side Scripting
Forum Library, Charter, Moderators: coopster & jatar k

PHP Server Side Scripting Forum

    
posting variable to same page to use in UPDATE
Orangutang



 
Msg#: 4220446 posted 4:22 pm on Oct 22, 2010 (gmt 0)

Hi,

Ultimately what I'm trying to do is create an interface like your inbox. You pick from a select list the email to be moved to spam folder.

I'm trying to get a variable from the same page which is in a select form in a while loop. The page displays, I pick from the list and submit to itself.

I'm populating the name field with the orderid before I submit the form but it's not getting passed.

EG:
<input type="text" name="<?php echo $row['orderid'];?> " />

I'm doing this so I use it for stipulation in the UPDATE statement further down.

EG:
// connect to db
$orderID = $_POST['orderid'];
// more code
$query = "UPDATE orders SET status = '$status' WHERE orderid = '$orderID'";
$result = mysql_query ($query) or die (mysql_error());

$query = "SELECT * FROM `orders` WHERE `username` = '$username' AND `status` = 'expected' ORDER BY orderid ASC LIMIT 100";
$result = mysql_query ($query) or die (mysql_error());

while ($row = mysql_fetch_array($result))
{?>
// more code

If I change $orderID = $_POST['orderid']; to $orderID = '143'; it works which tells me its not passng it ok.

Is populating the name field as I've done incorrect, is that impossible or is there another method.

Thanks in advance for any help.

 

enigma1

WebmasterWorld Senior Member 5+ Year Member



 
Msg#: 4220446 posted 5:54 pm on Oct 22, 2010 (gmt 0)

You need to setup the name of the input element to be the same as with the one in your $_POST array

<input type="text" name="orderid" value="some value" />

If you have multiple input boxes you can setup an array and then use its name to fetch the contents of each box.

name="orderid[]"

if( isset($_POST['orderid']) && is_array($_POST['orderid']) ) {
$orders_array = $_POST['orderid'];
.....
}

Orangutang



 
Msg#: 4220446 posted 3:49 pm on Oct 24, 2010 (gmt 0)

Thanks for the help enigma 1, it works. I understand now that the input element name must be the same as the one in my POST array.

Strangely for me I still needed to populate the value of the name in the input element with the actual orderid no: I've streamlined the script to make it easier to see.

expectorders.php

<?php
session_start();
$username = (isset($_SESSION['user']) ? $_SESSION['user'] : 'Log in');
// connect to db
$status = $_POST['status'];
$orderID = $_POST['orderid'];
?>
<head></head><body>
<?php
echo "$orderID"; //just for debugging
echo "$status";?> // just for debugging
<br><hr><?php

$query = "UPDATE orders SET status = '$status' WHERE orderid = '$orderID'";
$result = mysql_query ($query) or die (mysql_error());

$query = "SELECT * FROM `orders` WHERE `username` = '$username' AND `status` = 'processed' ORDER BY orderid ASC LIMIT 100";
$result = mysql_query ($query) or die (mysql_error());

while ($row = mysql_fetch_array($result)) {
echo $row['status']; ?>
<br><?php
echo $row['orderid']; ?>
<br><?php
?>
<hr>
<form method="POST" action="expectorders.php">
<input type="text" name="orderid" value="<?php echo $row['orderid'];?>"/>
<select name="status">
<option value="expected">Expected</option>
<option value="late">Late</option>
<option value="processed">Processed</option>
<option value="quarantined">Quarantined</option>
</select>
<input type="submit" value="Update" />
</form>
<hr>
<?php
}
?>
</body>
</html

I must have orderid as name but I also need the bold in there or it doesn't work so I'm not sure what's happening there ?

///////////////////////////////////////////////////////////

Also I have got multiple input boxes so the array pointer is really useful thanks. But I'm struggling to understand.

I change it to name="orderid[]" which I assume sends an array.

Then I think with this:

if( isset($_POST['orderid']) && is_array($_POST['orderid']) ) {
$orders_array = $_POST['orderid'];
.....
}

I'm checking to see if the posted orderid has a value in it and then I check if orderid variable is an array then create the variable $orders_array. I appreciate its me not understanding but I'm not sure why I'm checking that.

Ultimately I think I'm after the status and the orderid for the UPDATE statement. For my understanding which is very limited the UPDATE statement won't work if there not there.

I know its me not understanding so any clarification on the if statement would be very helpful. I understand using an array because there are 2 input boxes but I don't understand because I only need status and orderid as individual variables.

I know you didn't have the full picture last post which is why I included it above so at least you have all the info now.

In summary if you could help with these questions I'd be much appreciated.

1. Why did I need to echo out the orderid in the value to enable it to be passed.

2. Do I completely misunderstand the array suggestion ?

Many thanks.

enigma1

WebmasterWorld Senior Member 5+ Year Member



 
Msg#: 4220446 posted 8:57 am on Oct 25, 2010 (gmt 0)

1. The echo command is performed on the server end and fills in the form so it includes the $row['orderid']. Without it you would need some other method to include it like a hidden field. Depends what the form field should display.

The value of the input element will show inside the edit box of the orderid. So it may display 1 or 2 or 3 etc. The value of the edit box can also change, someone may enter a or b or c in which case the orderid may not be what you expect. Therefore if the orderid is a fixed integer it will be better to use a hidden field because you do not expect it to change.

<input type="hidden" name="orderid" value="<?php echo $row['orderid'];?>" />

In this case the field won't display but it will still be part of the form.

2. The array suggestion is because I see a loop as you retrieve multiple orders from the database and you may want to change the state on all of them with a single click. The idea is to change multiple orders without making separate requests, reloading the page multiple times. In that case the form opens/closes outside the while loop then inside it you setup the various orders. When the form is submitted all the orders can be updated at the same time. If you only need one just ignore it although the sql indicates multiple rows to be fetched.

migthegreek

5+ Year Member



 
Msg#: 4220446 posted 10:16 am on Oct 25, 2010 (gmt 0)

Hi, Orangutan.

From what I can see, you want to list all orders that are 'processed' and be able to change their statuses and update all. It seems like the biggest problem you have is that you are trying to print out an individual form for each order row. You don't need to do that; you can use one form, and use POST arrays like enigma has said.

I have made you a complete example script for you, but please note it is completely untested. Let me know if there are any problems.

Basically, you retrieve your rows from the database. Then you loop through them within one form and create a select box for each, containing status options. The order ID is placed into a hidden form field, as you don't need it to be an editable text field.

When the form is posted, we simply check if the submit button was pressed. Then we take the array of posted statuses and match them with the array of posted order IDs so that we have one nice array called $statuses. Each array element has a key of the order ID and a value of its corresponding status. We loop through our new $statuses array and check if the status has changed. If it has, we update.

As I hope you will be able to see from the debugging lines I have put in, by adding square brackets after the name of the form fields status[] and orderid[], an array gets posted of all fields that have the same name (they are all part of the same array). This is what enables us to have many select boxes that are the same but are all in one form.

<?php
/**
* This function is just to aid with debugging. It will display the contents
* of an array in an easily readable fashion. You might want to keep it in
* another global file somewhere for reusability. It is used in the script
* below to show you what is happening with the arrays.
*/
function debug($var) {
echo '<pre>';
print_r($var);
echo '</pre>';
}

//*********************************************

// Check login
session_start();
$username = isset($_SESSION['user'] ? $_SESSION['user'] : 'Log in';

// CONNECT TO DATABASE HERE
// mysql_connect(...)

//*********************************************
// Process the form

if (isset($_POST['update'])) {

// (DEBUG) Show the information that was posted by the form
echo '<p>The order IDs posted from the form are:</p>';
debug($_POST['orderid']);
echo '<p>The statuses posted from the form are:</p>';
debug($_POST['status']);

// Combine posted order IDs and statuses into a nice array to work with
$statuses = array_combine($_POST['orderid'], $_POST['status']);

// (DEBUG) See what the combined information looks like
echo '<p>The combined array data is:</p>';
debug($statuses);

// Loop through our array
foreach ($statuses as $orderID => $status) {
// If the status has changed from 'processed', update the order
// otherwise we don't need to bother.
if ($status != 'processed') {
$query = "UPDATE orders SET status = '$status' WHERE orderid = '$orderID'";
$result = mysql_query ($query) or die (mysql_error());

// (DEBUG) See which rows updated
echo "<p>Order '$orderid' status changed from <i>processed</i> to <i>$status</i>.</p>";
}
}
}

//*********************************************
// Get all orders with a status of 'processed'

$query = "SELECT * FROM `orders` WHERE `username` = '$username' AND `status` = 'processed' ORDER BY orderid ASC LIMIT 100";
$orders = mysql_query($query) or die(mysql_error());

?>
<head></head>

<body>
<form method="post" action="expectorders.php">

<?php while ($row = mysql_fetch_assoc($orders)) : ?>

<h3><?php echo $row['orderid']; ?></h3>
<select name="status[]">
<option value="expected">Expected</option>
<option value="late">Late</option>
<option value="processed" selected="selected">Processed</option>
<option value="quarantined">Quarantined</option>
</select>
<input type="hidden" name="orderid[]" value="<?php echo $row['orderid'] ?>" />
<hr />

<?php endwhile; ?>

<input type="submit" name="update" value="Update" />
</form>
</body>
</html>

Orangutang



 
Msg#: 4220446 posted 10:32 am on Oct 26, 2010 (gmt 0)

Hi Guys,

Thanks for the help. You were both one step ahead of me, I do want to change multiple orders at the same time but I was having problems locating the </form> end tag (surprise) which is why I thought I'd try one at a time first.

I was also quite a long way off in structural design and doc flow let alone the arrays and loops but I'm a lot clearer now. I now understand your deductions enigma 1.

I copied your post migthegreek and it worked really well.

I really like this:
$statuses = array_combine
foreach ($statuses as $orderID => $status) {
if ($status != 'processed') {

What a cool way to get the job done.

I've now done the other pages late, processed etc on the main site and everything works really well.

Thanks for taking the time to explain things and write the example script for me. I learned a hell of a lot from it so thanks very much for that.

Cheers O

enigma1

WebmasterWorld Senior Member 5+ Year Member



 
Msg#: 4220446 posted 2:00 pm on Oct 26, 2010 (gmt 0)

The array_combine will break if the form is submitted without one of the input fields or when there is a mismatch. It returns false instead of an empty array (another great PHP5 feature) This means the application may print a notice subject to the error level without error checking.

Best to use a single field for both, compatible with older PHP versions and simpler. So your form could be

<form method="post" action="expectorders.php">
......
<select name="status[<?php echo $row['orderid'];?>]">
......
Then for processing:

$status_array = isset($_POST['status']) && is_array($_POST['status'])?$_POST['status']:array();
foreach($status_array as $order_id => $selection) {
.......
}

Easier to use functions that are type-consistent on their return value. Otherwise you will need to put error checking for mixed return types.

Orangutang



 
Msg#: 4220446 posted 7:50 pm on Oct 26, 2010 (gmt 0)

Hi enigma1,

I understand what you've said but I'm struggling to implement it into my test script. I see what you mean about submitting the status array with the echoed out orderid as an array value and I'm following onto $status_array = isset($_POST['status']) && is_array($_POST['status'])?$_POST['status']:array();

but after that I'm lost.

I've posted my test script below with the amendments, ie: implemented your suggestion and removed the hidden orderid field from the form. I'm following until we get to the foreach loop then the bold indicates where i'm getting lost.

<?php
session_start();
$username = (isset($_SESSION['user']) ? $_SESSION['user'] : 'Log in');
// connect to db

$status_array = isset($_POST['status']) && is_array($_POST['status'])?$_POST['status']:array();
foreach($status_array as $order_id => $selection) {

// I'm not sure where these 2 vars have come from or how they came to be and because of that I can't make progress on the bold below.

if ($status != 'expected') {
$query = "UPDATE orders SET status = '$status' WHERE orderid = '$order_id'";
$result = mysql_query ($query) or die (mysql_error());

echo "<p>Order '$order_id' status changed from <i>expected</i> to <i>$status</i>.</p>";
}
}
$query = "SELECT * FROM `orders` WHERE `username` = '$username' AND `status` = 'expected' ORDER BY orderid ASC LIMIT 100";
$orders = mysql_query($query) or die(mysql_error());
?>

<head></head><body>
<form method="post" action="expectorders.php">
<?php while ($row = mysql_fetch_assoc($orders)) : ?>
<h3><?php echo $row['orderid']; ?></h3>

<select name="status[<?php echo $row['orderid'];?>">
<option value="expected" selected="selected">Expected</option>
<option value="late">Late</option>
<option value="processed">Processed</option>
<option value="quarantined">Quarantined</option>
</select>
<hr />
<?php endwhile; ?>
<input type="submit" name="update" value="Update" />
</form>
</body>
</html>

If you could point out the error in my ways it would be much appreciated. I'd like to get it working but hopefully you can see that I'm not going to be able to do it.

Many thanks

enigma1

WebmasterWorld Senior Member 5+ Year Member



 
Msg#: 4220446 posted 8:53 am on Oct 27, 2010 (gmt 0)

The 2 variables in bold are coming from the array posted. Each entry in an array may have 2 elements. A key and a value. By default keys are integers starting from 0.
eg:
array('red','green') is the same as
array(
0 => 'red'
1 => 'green'
);

But it could be set:
array(
'color1' => 'red'
'color2' => 'green'
);

So in your code $selection is the value of the drop-down list for the row ie: the $status you used you could make it:

foreach($status_array as $order_id => $status) {
if ($status != 'expected') {
$query = "UPDATE orders SET status = '" . mysql_real_escape_string($status) . "' WHERE orderid = '" . (int)$order_id . "'";
$result = mysql_query ($query) or die (mysql_error());

echo "<p>Order '$order_id' status changed from <i>expected</i> to <i>$status</i>.</p>";
}

Can be improved further using a fixed array for the valid statuses at the beginning of the script:
$fixed_array = array(
'expected',
'late',
'processed',
'quarantined',
);

Then in the loop instead of
if ($status != 'expected') {

you could have
if ($status != 'expected' && in_array($status, $fixed_array) ) {
.........
}

The various checks are used because you don't want someone to post his own "strings" and mess the table.

Orangutang



 
Msg#: 4220446 posted 5:04 pm on Oct 28, 2010 (gmt 0)

Thanks for the explanations, I was wondering what checking to see if its set was actually checking. I've got it working with your code now:

posting:
<select name="selection[<?php echo $row['orderid'];?>]">

processing:
$status_array = isset($_POST['selection']) && is_array($_POST['selection'])?$_POST['selection']:array();
foreach($status_array as $order_id => $status) {
echo $order_id." - ".$status."<hr />";

if ($status!= 'expected' ) {
$query = "UPDATE orders SET status = '" . mysql_real_escape_string($status) . "' WHERE orderid = '" . (int)$order_id . "' ";
$result = mysql_query ($query) or die (mysql_error());
echo "<p>Order '$order_id' status changed from <i>expected</i> to <i>$status</i>.</p>";
}
}

On the last post I was missing one of the ] on the end of the posting statement as well. Grrr

///////////////////////////////////////////////

I've been looking at the $fixed_array method and i was hoping you could help me get to the bottom of it. I'm doing something very wrong here but I'm going down this angle to try to get it going: I cannot work out how to assign the orderid variable to the fixed arrays keys.

$test_array = isset($_POST['selection']) && is_array($_POST['selection'])?$_POST['selection']:array();
foreach($test_array as $orderid => $status) {
echo "$orderid <hr />";

$fixed_array = array('expected'=>$orderid, 'late'=>$orderid, 'processed'=>$orderid, 'quarantined'=>$orderid, );
foreach($fixed_array as $order_id => $status) {
echo $order_id." - ".$status."<hr />";

if ($status != 'expected' && in_array($order_id, $fixed_array) ) {
$query = "UPDATE orders SET status = '" . mysql_real_escape_string($status) . "' WHERE orderid = '" . (int)$order_id . "' ";
$result = mysql_query ($query) or die (mysql_error());
echo "<p>Order '$order_id' status changed from <i>expected</i> to <i>$status</i>.</p>";
}
}
}

I've added the isset statement, looped through and echoed out the orderid because I was trying to add it into the fixed array as the key. I know this can't be right, I'm doubling up on my code and I can't seem to assign the orederid variable as the key in the fixed array anyway. I know something very wrong but how would I get the posted orderid in order to use it?

Many thanks O

enigma1

WebmasterWorld Senior Member 5+ Year Member



 
Msg#: 4220446 posted 7:16 pm on Oct 28, 2010 (gmt 0)

You don't assign them to the fixed array the order id comes in from the posted array $status_array in other words. The fixed array is not used in that loop but should be used for the validation. You first set it up like

$fixed_array = array('expected', 'late', 'processed', 'quarantined');
Its keys are automatically setup as integers beginning from 0. So the foreach loop in the array should be using the posted values of the select fields

$status_array = isset($_POST['status']) && is_array($_POST['status'])?$_POST['status']:array();
foreach($status_array as $orderid => $status) {
if ($status != 'expected' && in_array($status, $fixed_array) ) {
// Do query here
}
So before using the $orderid and the sql query you check to see if the status is valid. So the $fixed_array is only used to verify the status is valid before performing the query.

Orangutang



 
Msg#: 4220446 posted 12:55 pm on Nov 1, 2010 (gmt 0)

Hi enigma1, thanks for the clarity. It all works as is should do now. I was struggling to work out the interaction between the value $status in the posted array and the $fixed arrays keys. I couldn't understand how the $status would be checked.

The main reason was that I didn't see the purpose of the check. As you say the $fixed_array is only used to verify the status is valid before performing the query. IE: check to see if expected, late, processed and quarantined were actually there.

I'm still not sure why this check is done. I noticed you added mysql_real_escape_string and (int) earlier on, I was wondering where to put the escape string so thanks for that.

I understand the need to sanitize data from users for obvious reasons but I didn't realise it needed to be done once the data had been sanitized and entered the application.

For instance if there was a checkbox, and select list with no place for the user to define the input why would we still need to sanitize the data. I appreciate now it needs doing but I'm struggling to understand why.

Hence this brings me to wondering why checking the $status against a fixed array is needed ?

Thanks for your help with all this, I know arrays are well used in php so it's good to understand them a bit better.

Many thanks O

enigma1

WebmasterWorld Senior Member 5+ Year Member



 
Msg#: 4220446 posted 2:13 pm on Nov 1, 2010 (gmt 0)

A checkbox as an input doesn't imply it will be posted as a checkbox. It can be posted as a textarea or input and its value doesn't mean is going to be a string or an integer. It can be an array.

So you treat every field posted for the form you process, as untrusted. Each field you process, you always verify it by type and by value. There are also different requirements when sanitize, to display content and for the database. The mysql_real_escape_string or direct type casts apply to database input.

The content is not critical by good to sanitize too. For instance someone could post the form and try to terminate an input field by posting a tag delimiter in the value like >. There are php functions to deal with this. I usually deploy few wrappers to sanitize input, easier to manage the code.

Orangutang



 
Msg#: 4220446 posted 6:59 pm on Nov 1, 2010 (gmt 0)

Cool, I understand what isset and is_array is actually doing now, in the context of the script and what empty() is doing on my login.

Its great to read the code and have a lot better idea about what's going on. I look forward to having a look into the wrappers and thanks again for helping me understand all this.

Cheers

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / PHP Server Side Scripting
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved