0

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();
?>
2
  • "Why isn't this code working?" questions are typically closed. A question should be about a specific problem. Your edit is shifting the purpose of the question and makes the answers irrelevant, so I am going to revert it. If you have a new question, post it as a specific new question :) Commented May 25, 2016 at 14:37
  • Thanks Chris, sorry about that. As I said I am very new to this and am not even sure about my structuring of the document, and was thinking that it might have something to do with that. I'm trying out your answer now :) Commented May 26, 2016 at 0:49

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

3 Comments

@ChrisBaker - hey, sorry if I adjust my answer so that my answer will be clear enough for the OP. But I think, the only part that my answer is the same with yours is the json_encode() and json_decode. I can remove that part if you want. Doesn't care about points either.
@LoganWayne I have followed your instructions but I am running into errors, maybe because the array isn't being "indexed"? So, the following is now sitting in my UserData field on the db: ["Title","Subtitle","Footer"] But, on page load when trying to get that data, I'm receiving the following: Notice: Undefined offset: 0 in C:\xampp\htdocs\PHPlogin\v2\edit.php on line 38 Am I right to assume this is because the array doesn't include the "keys" which correspond to the input number?
@LankyMoose - Use json_decode() after fetching the data, then run them all using foreach() or any loop alike.
0

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

2 Comments

Hey Chris, thanks for that. The thing is, I want to be able to have X number of inputs which will be dynamically created via front end magic. If I wasn't to store the data in one column, would that mean that I'd have to be creating extra columns on the go, or maybe on backup (thinking of maybe like 100 extra db columns that haven't been used yet, hidden on page, js displays and if used they are encoded and so on?
@LankyMoose Dynamically created fields is a fair enough reason to use a single column, just encode the array into a string as shown here and you're fine. Make sure to look in to the other issues I mentioned, especially the safer queries.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.