简体   繁体   中英

Storing multiple input values in single field in database and retrieving separately

So, I have a form like so:

<form action="edit.php" method="POST" id="content">
    <h3>Homepage</h3>
    <hr/>
    <h4>Title: </h4><input type="text" name="UserData[]" value='$UserData[]'><br/>
    <h4>Subtitle: </h4><input type="text" name="UserData[]" value='$UserData[1]'><br/>
    <h4>Footer: </h4><input type="text" name="UserData[]" value='$UserData[2]'><br/>
    <input type="submit" value="Save" name="datasave" id="save">
</form>

PHP submit:

if(isset($_POST['datasave']))
{
    $data = $_POST['UserData'];
    $Userdata = mysqli_escape_string($con, $data);
    $query = "UPDATE users 
    SET UserData = '$UserData' WHERE Username = '$Username'";
    mysqli_query($con, $query);
}

Getting values from DB to display in fields:

$GetUserData = "SELECT UserData FROM users WHERE Username = '$Username'";
$UpdatedUserData= mysqli_query($con,$GetUserData);
if (! $UpdatedUserData){
    echo "error";
}
while($row = mysqli_fetch_assoc($UpdatedUserData)){
    $UserData = $row['UserData'];
}

I should probably note that I am a novice PHP & mysql user (please bear with me). The problem is, this doesn't work and I'm obviously missing something & not doing this as efficiently as I could be... How can I get the values of my multiple inputs and store them in the same db field? As you can see, I'd like each of the values to automatically be added to their respective field on page load.

EDIT: I have taken this down to barebones (removing other code etc.) and restructured a bit, which has done the trick! Now to learn about parameterized queries :D

<?php
require('config.php');
session_start();

$Username = $_SESSION['username'];

$GetUserData = "SELECT UserData FROM users WHERE Username = '$Username'";
$UpdatedUserData= mysqli_query($con,$GetUserData);

$row = mysqli_fetch_assoc($UpdatedUserData);

$data = json_decode($row["UserData"]);


foreach($data as $eachdata ) {
    $UserData[] = $eachdata;
}
if ( $UserData ) {
    echo '<form action="edit.php" method="POST" id="content">
              <h3>Homepage</h3>
              <hr/>
              <h4>Title: </h4><input type="text" name="UserData[]" value="'.$UserData[0].'"><br/>
              <h4>Subtitle: </h4><input type="text" name="UserData[]" value="'.$UserData[1].'"><br/>
              <h4>Footer: </h4><input type="text" name="UserData[]" value="'.$UserData[2].'"><br/>
              <input type="submit" value="Save" name="datasave" id="save">
         </form>';
} else {
    die("Error: {$con->errno} : {$con->error}");
}
if(isset($_POST['datasave']))
{
    $data = json_encode($_POST['UserData']);
    $query = "UPDATE users 
    SET UserData = '$data' WHERE Username = '$Username'";
    mysqli_query($con, $query);

    if (mysqli_query($con, $query)) {
        header("Location: edit.php");   
    } else {
        echo "Error updating record: " . mysqli_error($con);
    }
}

if ( $con->connect_error ) {
    die( 'Connect Error: ' . $con->connect_errno . ': ' . $con->connect_error );
}  
$con->close();
?>

Questions first:

  • Where does $Username variable coming from?

  • Do you really intend to store an array to your users.UserData column?

If you want to continue this schema of yours, you have to figure out how to store them to your database. You will encounter an error if you try to use *_real_escape_string() if you use it in an array. Second parameter will be looking for strings, not for an array.

You can try to run them all and then use *_real_escape_string and then restore them.

for($x = 0; $x < count($_POST["UserData"]); $x++){

  $data[$x] = mysqli_real_escape_string($con, $data[$x]);

}

Did you properly concatenate the variable to your HTML form?

echo '<form action="edit.php" method="POST" id="content">
          <h3>Homepage</h3>
          <hr/>
          <h4>Title: </h4><input type="text" name="UserData[]" value="'.$UserData[0].'"><br/>
          <h4>Subtitle: </h4><input type="text" name="UserData[]" value="'.$UserData[1].'"><br/>
          <h4>Footer: </h4><input type="text" name="UserData[]" value="'.$UserData[2].'"><br/>
          <input type="submit" value="Save" name="datasave" id="save">
     </form>';

@ChrisBaker covers the rest of storing and retrieving the data from your database.


Standard way of storing Data

But the advisable way to store such data in your database is to restructure your table in your database. Separate each into their own column:

Your users table will look like:

id |  Username   |   title   | subtitle  | footer  |
---+-------------+-----------+-----------+---------+
 1 | LankyMoose  |    OP     |  English  | sticky  |
 2 | Chris Baker | Boy Scout |  English  | dynamic |
 3 | Logan Wayne |   Whiner  |   Multi   |  none   |

So you can store them to your database and fetch them easier.


Dynamic Storing of Data

But what if those fields are dynamic? You want to store more data from the user ( that is what I thought of when you try to insert an array of data from the user ).

You can create extra tables that stores the different types of data from the user and stores the user's input. Lets name the first table for example, data_table :

 data_id | data_type
---------+-----------
    1    |   Title
    2    |   Subtitle
    3    |   Footer

Then for the second table which stores the users input, lets name it data_input :

input_id | data_id | user_id | user_input
---------+---------+---------+------------
    1    |    1    |    1    |     OP
    2    |    2    |    1    |   English
    3    |    3    |    1    |    sticky
    4    |    1    |    2    |  Boy Scout
    5    |    2    |    2    |   English
    6    |    3    |    2    |   dynamic
    7    |    1    |    3    |   Whiner
    8    |    2    |    3    |   Multi
    9    |    3    |    3    |    none

Your users table would look like this now:

user_id |   username    
--------+-------------
   1    |  LankyMoose
   2    |  Chris Baker
   3    |  Logan Wayne

So for example, you want to get data from LankyMoose , you can try this query:

SELECT a.username,
       c.data_type,
       b.user_input
FROM users a
     LEFT JOIN data_input b ON a.user_id = b.user_id
     LEFT JOIN data_table c ON b.data_id = c.data_id
WHERE user_id = 1

Result will be:

  username  | data_type | user_input
------------+-----------+------------
 LankyMoose |   Title   |    OP
 LankyMoose |  Subtitle |  English
 LankyMoose |   Footer  |   sticky

With this method, you can add more fields just by inserting data to data_table .


I would also suggest that you use prepared statement since you are already using mysqli_* extension.

The first and most obvious answer is more of a question: why store them all in one database column? You may have your reasons, but examine them again, this is not standard. One would typically have a database table with specific fields for each value.

Assuming it isn't possible or practical to use multiple fields, you cannot simply toss a PHP array into the database and get it out later. Using mysqli_escape_string is not doing what you expect -- as the name implies, it wants a string and you're giving it an array. You must convert the PHP scalar array into something the database can work with, most likely a string. You have a few options there. You can use serialize , or json_encode . Of the two, I suggest JSON.

If you encode the array to a string, you will of course have to convert it BACK to a value PHP can work with, you have to decode it.

To encode to JSON:

$data = json_encode($_POST['UserData']);

... and to decode:

$UserData = json_decode($row['UserData'], true);

You can also dispense with the numerically indexed items by crafting your fields as follows:

<input type="text" name="UserData[title]" value=<?=($UserData['title'])?>>

I would be remiss if I did not mention that you should switch to parameterized queries, otherwise you are open for an SQL injection attack. See more: http://php.net/manual/en/mysqli.quickstart.prepared-statements.php -- manual escaping with mysqli_escape_string is cumbersome and one is apt to neglect to escape everything correctly.

Your query and use of a while loop leaves open the possibility that more than one user with the given username will be found. The while loop will go through these, until the last one, then proceed to your form. If it is fair to say that you will only get one row back, only one user will have the given username, dispense with the while loop and simply fetch the data one time. You may also want to put a LIMIT 1 restriction on the query, and put a unique index on the column in the database.

Documentation/Further Reading

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM