Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am trying to filter use a form to filter a database then provide a way to update the filtered data. I may not being doing it the best way, but it is close to working. The problem seems to be that when I press the "Update" button, a few variables are cleared; count and ID.

I have fixed count by making it a session variable, but there isn't a way to do it with ID. I am not sure why count gets erased, so I would appreciate if someone could tell me.

The update part of my code works perfectly when used without the filter part, again, the problem is that the id variable is empty. I have tested all other variables and put a constant in for ID for testing in my update statement. Here is my code.

<?php
session_start();
?>

<?php
$host="localhost"; // Host name 
$username=""; // Mysql username 
$password=""; // Mysql password 
$db_name="inventory"; // Database name 
$tbl_name="computers"; // Table name
// Connect to server and select databse.
mysql_connect("$host", "$username", "$password")or die("cannot connect"); 

mysql_select_db("$db_name")or die("cannot select DB");

// Get values from form 
$school=$_POST['school'];
$make=$_POST['make'];
$model=$_POST['model'];
$barcode=$_POST['barcode'];
$location=$_POST['location'];
?>

    <?php
    include 'nav-bar.php';
    ?>

    <h2 align="center">Filter Computers</h2>
    <form name="form" method="post" style="margin: 0; text-align: center;">
    <p><label>School Name:</label><input type="text" name="school" size="8" id="school" tabindex="1"</p>
    <p><label>Make:</label><input type="text" name="make" size="25" id="make" tabindex="1"</p>
    <p><label>Model:</label><input type="text" name="model" size="25" id="model" tabindex="1"</p>
    <p><label>Barcode:</label><input type="text" name="barcode" size="12" id="barcode" tabindex="1"</p>
    <p><label>Location:</label><input type="text" name="location" size="25" id="location" tabindex="1"</p>
    <p><label>Serial:</label><input type="text" name="serial" size="25" id="location" tabindex="1"</p>
    <p><label>Date Acquired yyyy-dd-mm:</label><input type="text" name="date" size="8" id="location" tabindex="1"</p>
    <p><label>Processor:</label><input type="text" name="processor" size="25" id="location" tabindex="1"</p>
    <p><label>RAM:</label><input type="text" name="ram" size="25" id="location" tabindex="1"</p>
    <p><input align="center" type="submit" name="Filter" value="Filter">
    </form>

    <?php

    if($_POST['Filter']){
    $sql = "SELECT * FROM $tbl_name WHERE school like '%$school' AND make like '%$make' AND model like '%$model' AND location like '%$location'";
    $result=mysql_query($sql);

    // Count table rows 
    $count=mysql_num_rows($result);
    $_SESSION['count']=$count;


    ?>

    <strong>Update Multiple Computers</strong><br> 
    <table width="500" border="0" cellspacing="1" cellpadding="0">
    <form name="form1" method="post" action="">
    <tr> 
    <td>
    <table width="500" border="0" cellspacing="1" cellpadding="0">


    <tr>
    <td align="center"><strong>Id</strong></td>
    <td align="center"><strong>School</strong></td>
    <td align="center"><strong>Make</strong></td>
    <td align="center"><strong>Model</strong></td>
    <td align="center"><strong>Barcode</strong></td>
    <td align="center"><strong>Location</strong></td>
    </tr>

    <?php
    while($rows=mysql_fetch_array($result)){
    ?>
    <tr>
    <td align="center"><?php $id[]=$rows['id']; ?><?php echo $rows['id']; ?></td>
    <td align="center"><input name="school[]" type="text" id="school" value="<?php echo $rows['school']; ?>"></td>
    <td align="center"><input name="make[]" type="text" id="make" value="<?php echo $rows['make']; ?>"></td>
    <td align="center"><input name="model[]" type="text" id="model" value="<?php echo $rows['model']; ?>"></td>
    <td align="center"><input name="barcode[]" type="text" id="barcode" value="<?php echo $rows['barcode']; ?>"></td>
    <td align="center"><input name="location[]" type="text" id="location" value="<?php echo $rows['location']; ?>"></td>
    </tr>

    <?php
    }
    ?>
    <tr>
    <td colspan="4" align="center"><input type="submit" name="Update" value="Update"></td>
    </tr>
    </table>
    </td>
    </tr>
    </form>
    </table>
    <?php
    }
    // Check if button name "Update" is active, do this 
    if(isset($_POST['Update'])){
    for($i=0;$i<$_SESSION['count'];$i++){
    $sql1="UPDATE $tbl_name SET school='$school[$i]', make='$make[$i]', model='$model[$i]' , barcode='$barcode[$i]' , location='$location[$i]' WHERE id='$id[$i]'";
    $result1=mysql_query($sql1);
    }
    session_destroy();
    }
    if(isset($result1)){
    echo "<meta http-equiv=\"refresh\" content=\"0;URL=update_multiple.php\">";
    }
    ?>`

Any help is surely appreciated.

share|improve this question

3 Answers 3

up vote 0 down vote accepted

Please check this out... I have added two lines in your code and ID is being fetched and you can update data accordingly. I have commented as NOTE HERE..

<?php
$host="localhost"; // Host name 
$username=""; // Mysql username 
$password=""; // Mysql password 
$db_name="inventory"; // Database name 
$tbl_name="computers"; // Table name
// Connect to server and select databse.
mysql_connect("$host", "$username", "$password")or die("cannot connect"); 

mysql_select_db("$db_name")or die("cannot select DB");

// Get values from form 
$school=$_POST['school'];
$make=$_POST['make'];
$model=$_POST['model'];
$barcode=$_POST['barcode'];
$location=$_POST['location'];
//Note here
$id = $_POST['id'];
?>

    <?php
    include 'nav-bar.php';
    ?>

    <h2 align="center">Filter Computers</h2>
    <form name="form" method="post" style="margin: 0; text-align: center;">
    <p><label>School Name:</label><input type="text" name="school" size="8" id="school" tabindex="1"</p>
    <p><label>Make:</label><input type="text" name="make" size="25" id="make" tabindex="1"</p>
    <p><label>Model:</label><input type="text" name="model" size="25" id="model" tabindex="1"</p>
    <p><label>Barcode:</label><input type="text" name="barcode" size="12" id="barcode" tabindex="1"</p>
    <p><label>Location:</label><input type="text" name="location" size="25" id="location" tabindex="1"</p>
    <p><label>Serial:</label><input type="text" name="serial" size="25" id="location" tabindex="1"</p>
    <p><label>Date Acquired yyyy-dd-mm:</label><input type="text" name="date" size="8" id="location" tabindex="1"</p>
    <p><label>Processor:</label><input type="text" name="processor" size="25" id="location" tabindex="1"</p>
    <p><label>RAM:</label><input type="text" name="ram" size="25" id="location" tabindex="1"</p>
    <p><input align="center" type="submit" name="Filter" value="Filter">
    </form>

    <?php

    if($_POST['Filter']){
    $sql = "SELECT * FROM $tbl_name WHERE school like '%$school' AND make like '%$make' AND model like '%$model' AND location like '%$location'";
    $result=mysql_query($sql);

    // Count table rows 
    $count=mysql_num_rows($result);
    $_SESSION['count']=$count;


    ?>

    <strong>Update Multiple Computers</strong><br> 
    <table width="500" border="0" cellspacing="1" cellpadding="0">
    <form name="form1" method="post" action="">
    <tr> 
    <td>
    <table width="500" border="0" cellspacing="1" cellpadding="0">


    <tr>
    <td align="center"><strong>Id</strong></td>
    <td align="center"><strong>School</strong></td>
    <td align="center"><strong>Make</strong></td>
    <td align="center"><strong>Model</strong></td>
    <td align="center"><strong>Barcode</strong></td>
    <td align="center"><strong>Location</strong></td>
    </tr>

    <?php
    while($rows=mysql_fetch_array($result)){
    ?>
    <tr>
    <td align="center"><?php $id[]=$rows['id']; ?><?php echo $rows['id']; ?></td>
    <td align="center"><input name="school[]" type="text" id="school" value="<?php echo $rows['school']; ?>"></td>
    <td align="center"><input name="make[]" type="text" id="make" value="<?php echo $rows['make']; ?>"></td>
    <td align="center"><input name="model[]" type="text" id="model" value="<?php echo $rows['model']; ?>"></td>
    <td align="center"><input name="barcode[]" type="text" id="barcode" value="<?php echo $rows['barcode']; ?>"></td>
    <td align="center"><input name="location[]" type="text" id="location" value="<?php echo $rows['location']; ?>"></td>
    <!-- Note here-->
    <input type="hidden" name="id[]" id="id" value="<?php echo $rows['id']; ?>" />
    </tr>

    <?php
    }
    ?>
    <tr>
    <td colspan="4" align="center"><input type="submit" name="Update" value="Update"></td>
    </tr>
    </table>
    </td>
    </tr>
    </form>
    </table>
    <?php
    }
    // Check if button name "Update" is active, do this 
    if(isset($_POST['Update'])){
    for($i=0;$i<$_SESSION['count'];$i++){
    $sql1="UPDATE $tbl_name SET school='$school[$i]', make='$make[$i]', model='$model[$i]' , barcode='$barcode[$i]' , location='$location[$i]' WHERE id='$id[$i]'";
    $result1=mysql_query($sql1);
    }
    session_destroy();
    }
    if(isset($result1)){
    echo "<meta http-equiv=\"refresh\" content=\"0;URL=update_multiple.php\">";
    }
    ?>

I hope that will help you.

share|improve this answer
    
This worked perfectly! Thank you very much. I noticed that you added $id = $_POST['id']. The correct ID would display when pressing filter, but wasn't available when pressing update. Can you explain why? –  Brian Mar 7 '12 at 22:04
    
When you press filter at that time, you get $id but when you press update of multiple form at that time, $id is not available in your second form of update,so you can't get the value of $id in post... So you need to pass it as input in that form... Glad to help you.. –  Kamal Mar 8 '12 at 10:40
    
Is it because id isn't an input type on the second form? If so that makes sense. –  Brian Mar 9 '12 at 15:13
    
Yeah exactly... –  Kamal Mar 9 '12 at 18:23

You shouldn't make count a session variable, and you should have a single form - you can have multiple submit buttons to it.

In a form, only things between <form> and </form> are submitted.

Here is an improved refactored version of your code:

<?php

// Database connection settings
$host     = 'localhost';
$username = '';
$password = '';
$db_name  = 'inventory';
$tbl_name = 'computers';

// Connect to server and select database.
mysql_connect($host, $username, $password) or die('cannot connect'); 
mysql_select_db($db_name) or die('cannot select DB');

// Perform updates
if (isset($_POST['Update']))
{
    $value_fields = array('school', 'make', 'model', 'barcode', 'location');

    foreach ((array) $_POST['id'] as $counter => $id)
    {
        $user_values = array();
        foreach($value_fields as $field_name)
        {
            if (isset($_POST[$field_name][$counter]))
            {
                $user_values[] = $field_name . ' = "' . mysql_real_escape_string($_POST[$field_name][$counter]) . '"';
            }
        }
        if (!empty($user_values))
        {
            $sql = 'UPDATE ' . $tbl_name . ' SET ' . implode(', ', $user_values) . ' WHERE id = "' . intval($id) . '"';
            mysql_query($sql);
        }
    }
}

// Build select command
$where = array('TRUE');

$filter_fields = array('school', 'make', 'model', 'barcode', 'location', 'serial', 'date', 'processor', 'ram');

if (empty($_POST['filter']))
{
    $user_filter = array_fill_keys($filter_fields, '');
}
else
{
    $user_filter = (array) $_POST['filter'];

    foreach($filter_fields as $filter_field)
    {
        if (empty($user_filter[$filter_field]))
        {
            $user_filter[$filter_field] = '';
        }
        else
        {
            $term = str_replace(array('=', '_', '%'), array('==', '=_', '=%'), $user_filter[$filter_field]);
            $term = mysql_real_escape_string($term);
            $where[] = $filter_field . ' LIKE "%' . $term . '%" ESCAPE "="';
        }
    }
}

$sql = 'SELECT id, school, make, model, barcode, location FROM ' . $tbl_name . ' WHERE ' . implode(' AND ', $where);
$result = mysql_query($sql);

// Output
function safe_output($str)
{
    return str_replace(array("'", '"'), array("&#39;", "&quot;"), htmlspecialchars($str));
}

?>

<?php include('nav-bar.php'); ?>

<form method="post">
    <h2 align="center">Filter Computers</h2>
    <div style="margin: 0; text-align: center;">
        <p><label>School Name:</label><input type="text" name="filter[school]" size="8" value="<?php echo safe_output($user_filter['school']); ?>" /></p>
        <p><label>Make:</label><input type="text" name="filter[make]" size="25" value="<?php echo safe_output($user_filter['make']); ?>" /></p>
        <p><label>Model:</label><input type="text" name="filter[model]" size="25" value="<?php echo safe_output($user_filter['model']); ?>" /></p>
        <p><label>Barcode:</label><input type="text" name="filter[barcode]" size="12" value="<?php echo safe_output($user_filter['barcode']); ?>" /></p>
        <p><label>Location:</label><input type="text" name="filter[location]" size="25" value="<?php echo safe_output($user_filter['location']); ?>" /></p>
        <p><label>Serial:</label><input type="text" name="filter[serial]" size="25" value="<?php echo safe_output($user_filter['serial']); ?>" /></p>
        <p><label>Date Acquired yyyy-dd-mm:</label><input type="text" name="filter[date]" size="8" value="<?php echo safe_output($user_filter['date']); ?>" /></p>
        <p><label>Processor:</label><input type="text" name="filter[processor]" size="25" value="<?php echo safe_output($user_filter['processor']); ?>" /></p>
        <p><label>RAM:</label><input type="text" name="filter[ram]" size="25" value="<?php echo safe_output($user_filter['ram']); ?>" /></p>
        <p><input align="center" type="submit" value="Filter">
    </div>

    <strong>Update Multiple Computers</strong><br> 
    <table width="500" border="0" cellspacing="1" cellpadding="0">
        <tr>
            <td align="center"><strong>Id</strong></td>
            <td align="center"><strong>School</strong></td>
            <td align="center"><strong>Make</strong></td>
            <td align="center"><strong>Model</strong></td>
            <td align="center"><strong>Barcode</strong></td>
            <td align="center"><strong>Location</strong></td>
        </tr>
<?php while ($row = mysql_fetch_array($result)): ?>
        <tr>
            <td align="center"><input name="id[]" type="hidden" value="<?php echo $row['id']; ?>" /><?php echo $row['id']; ?></td>
            <td align="center"><input name="school[]" type="text" value="<?php echo safe_output($row['school']); ?>" /></td>
            <td align="center"><input name="make[]" type="text" value="<?php echo safe_output($row['make']); ?>" /></td>
            <td align="center"><input name="model[]" type="text" value="<?php echo safe_output($row['model']); ?>" /></td>
            <td align="center"><input name="barcode[]" type="text" value="<?php echo safe_output($row['barcode']); ?>" /></td>
            <td align="center"><input name="location[]" type="text" value="<?php echo safe_output($row['location']); ?>" /></td>
        </tr>
<?php endwhile; ?>
        <tr>
            <td colspan="6" align="center"><input type="submit" name="Update" value="Update" /></td>
        </tr>
    </table>
</form>

There is a lot to learn here:

  1. Separate the output or view (HTML) from the logic and processing code, the most possible. Note that the HTML starts only at the end. We have the least possible PHP code mixed with the HTML.

  2. If you don't clean your input ($_POST) and output (echo) you are vulnerable to several types of attack, like SQL injection and XSS. So, you always need to clean the user input before using it and the output before echoing it.

  3. To build both the UPDATE and the SELECT queries, we are using the implode function together with an array ($user_values for the UDPATE and $where for the SELECT).

  4. We are making the UPDATEs before the SELECT so the output appears updated.

  5. The LIKE clause is complicated to build correctly, because the user may want to search for "100%", but this percentage character can't be confused with the percentage of the SQL command. This is why we have some complicated and mysterious lines of code in this part.

  6. The mysql_real_escape_string and intval functions take care of cleaning the user input.

  7. We have made a safe_output function using htmlspecialchars and str_replace to clean the output.

  8. We have made an effort to have a complete $user_filter array arriving at the output phase.

  9. When the HTML starts, we have done everything: the safe UPDATES, the safe SELECT, the filters are in $user_filter array, and the results are in the $result resource. We only need to output.

  10. In the HTML, you can't have multiple elements with the same ID, and you don't need an ID for every form input. So, I removed the useless IDs.

  11. I have renamed the filter input names. Take a look. This way, we can have an array of filters.

  12. In this case, the "tabindex" attributes were useless, so they were also removed.

share|improve this answer
    
Thanks for all of the great information. I don't understand everything in your code, but plan on testing it and learning from it. I understand keeping html and php separate is a good practice but couldn't figure out what to do. I will look at your code in more detail soon. –  Brian Mar 7 '12 at 22:08
    
Start with the output. Then, understand what the whole "perform updates" and "build select command" block do (not each line, but what is the general purpose of each block). Add an echo $sql; line after the two $sql = something; lines, to see the SQL queries. But I think the most important thing to BEGIN is contemplating carefully the HTML only, which is very simple, and understanding that you don't need more than that. After understanding the HTML, then go for the PHP part. –  J. Bruni Mar 7 '12 at 22:41
    
I tested your code and it works fine. The drawback would be that both forms appear on the screen at once. I was going for a fill out the filter part, then your responses will appear type of interface. That is what got me to where I am. If I am going for a more dynamic type of interface, can I do it with HTML and PHP alone, or do I need to use some other language as well? –  Brian Mar 9 '12 at 15:16
    
It depends on what you want. You can easily add a <?php if ($show_filters): ?> line before the <h2 align="center">Filter Computers</h2> line, and <?php endif; ?> after the </div> line near below. Same thing for the second part: add a <?php if ($show_computers): ?> line before the <strong>Update Multiple Computers</strong><br> line, and <?php endif; ?> after the </table> line below. Then, before, in the PHP code, you can set $show_filters and $show_computers to TRUE or FALSE, as you like... –  J. Bruni Mar 9 '12 at 16:02
    
Will definitely test those methods of hiding. Thanks a lot! –  Brian Mar 10 '12 at 9:45

This is what hidden inputs are for. Add one for your id:

<input type="hidden" name="id[]" value="<?=$rows['id']?>" />

Also, you don't need to save the count. You can count the number of items in an array using count($id).

Finally, sanitize your inputs. Never put user submitted data straight into a query. Use intval for integers and mysql_real_escape_string for strings, or use prepared statements.

share|improve this answer
    
Thanks for the count($id) advice. I erased the session variable. Also thanks for the information on sanitizing the inputs. I have heard of it, and planned on looking into it if I put this in production. Currently it is a proof of concept. –  Brian Mar 7 '12 at 22:05

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.