-1

I have a table called assets in phpmyadmin which has a Responsible column. When an asset is created, with the help of $_SESSION["name"] I can put the right value into this column.

if($_SERVER["REQUEST_METHOD"] == "POST"){

    $id = $_POST['id']; 
    $name=$_POST['Asset_name'];
    $classification=$_POST['Classification'];
    $tag=$_POST['Tag'];
    $department=$_POST['Department'];
    $reviewdate=$_POST['Review_date'];
    $responsible=$_POST['Responsible'];
    $createdby=$_POST['Created_by'];

    // Making sure name is typed in and contains only letters
    if (empty(trim($name))) {
       $nameErr = "Name is required";
    } else {
        if (!preg_match("/^[a-zA-Z ]*$/", $name)) {
            $nameErr = "Only letters and white space allowed";
        }   
    }
    // Making sure tag is typed in and contains only letters
    if (empty(trim($tag))) {
        $tagErr = "Tag is required";
    } else {
        if (!preg_match("/^[a-zA-Z ]*$/", $tag)) {
            $tagErr = "Only letters and white space allowed";
        }
    }

    if (!empty($_POST) && ($nameErr == "") && ($tagErr == "")){    
        // Updating the table
        $result = mysqli_query($conn, "UPDATE assets SET Asset_name='$name',Classification='$classification',Tag='$tag',Department='$department',Review_date='$reviewdate', Responsible='$responsible' WHERE id='$id'");

        // Redirecting to assets.php
        header("Location: assets.php");
    }

However, these assets should be edited as well. I do it with a form where I loop through the users table "Name" column with this script:

mysqli_query($conn, "UPDATE assets SET Responsible='$responsible' WHERE id='$id'");

This is the script ("pdo" is the database specification but that works"):

$sql = "SELECT id,name FROM users";

// Prepare the select statement.
$stmt = $pdo->prepare($sql);

// Execute the statement.
$stmt->execute();

// Retrieve the rows using fetchAll.
$users = $stmt->fetchAll();

In the form this is what I use:

<?php   if($_SESSION['user_type'] == "admin") {
                        echo "<div class='form-group form-inline'>";
                        echo "<p class='formLabel'>Responsible</p>";                        
                        echo "<select class = 'select' name = 'Responsible' class='form-control' value=".$responsible.">";
                                foreach($users as $user):
                                    echo "<option value=".$user['name']."> ".$user['name']."</option>";
                                endforeach;
                                echo "</select>";
                    } else { echo "<input type='hidden' name = 'Responsible' value=".$_SESSION['name'].">";
                    }
            ?>  

When I choose the values from the list this script has created, they are the right ones, everything looks good. However, after clicking on Update, only the first name of that person is shown in the responsible column not the full name (e.g. John instead of John Williams) and I do not understand why. The users "Name" and the assets "Responsible" column are both varchar with 255 length. I suspect that my problem is with the query, but I dont know why. Can you help me? Thank you!

This are my tables: users assets

Szabolcs Magyar
  • 369
  • 1
  • 2
  • 11
  • 2
    You should read [How can I prevent SQL injection in PHP?](https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php/8255054) – Alex K. Jul 05 '19 at 10:51
  • Please add your table schema to the question, using `show create table assets` – grhn Jul 05 '19 at 10:52
  • well that is my point, there is no first name and last name, they both are in the users "Name" and the assets "Responsible" column as a full name, however, when clicking on update, it takes only the first name (until the space) into the database without the family name. Regarding the terminologies, yes, you are right, I started web development a month ago and everything seems fairly new to me. – Szabolcs Magyar Jul 05 '19 at 11:12
  • I am using action="" for submitting the form after clicking on update, so basically the form send itself and after submitting the form, the assets page is shown with all the assets present in that table – Szabolcs Magyar Jul 05 '19 at 11:20

1 Answers1

1

Your issue is that you aren't quoting your HTML attributes. This makes browsers break that value at the first space. Update your code to:

echo '<option value="' . $user['name']. '"> . $user['name']. '</option>';

This should resolve your issue. You also should look at XSS and SQL injections. This appears to be susceptible to both.

How can I prevent SQL injection in PHP?

Your select also shouldn't have a value attribute.

Each <option> element should have a value attribute containing the data value to submit to the server when that option is selected; if no value attribute is included, the value defaults to the text contained inside the element. You can include a selected attribute on an <option> element to make it selected by default when the page first loads.

-https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select

So change:

echo "<select class = 'select' name = 'Responsible' class='form-control' value=".$responsible.">";

into:

echo '<select class="select" name="Responsible" class="form-control">
<option value="' . $responsible. '" selected="selected">Unchanged</option>';
user3783243
  • 5,368
  • 5
  • 22
  • 41
  • 1
    Also a "select" html tag does not accept a "value" attribute. The value sent by request is the one in "option" tag. Read more https://www.w3schools.com/tags/tag_select.asp – Braza Jul 05 '19 at 11:28
  • 1
    @Braza Was just adding that as well. – user3783243 Jul 05 '19 at 11:28
  • One more thing, @Szabolcs Magyar, you should seriously consider using filter_var or filter_input for validation. Inputs are the main security issue on a front level. https://www.php.net/manual/en/function.filter-var.php Example: Instead of $id = $_POST['id']; filter_input(INPUT_POST, $id, FILTER_VALIDATE_INT); – Braza Jul 05 '19 at 11:31
  • @Braza so then trim, htmlspecialchars and stripslashes are not enough against XSS and SQL injections? – Szabolcs Magyar Jul 05 '19 at 11:36
  • `stripslashes ` and `trim ` don't help either. The `htmlspecialchars` won't stop because you are using single quotes for encapsulation. PHP generally assumes double quotes are used, `ENT_QUOTES` must be used so both quote types are encoded. Your regex solution won't allow names like `O'brien` to be written. Updating the regex will allow injection. Parameterize. You could use the regex front end for nicer error reporting. – user3783243 Jul 05 '19 at 11:38
  • Regarding the select value problem, if I want to store that option's value in the Responsible column, then am I right if I change the 2nd $user['name'] to $resposible or I should just delete it because of the select name="Responsible" it automatically stores the list's value in the database? And btw thanks for your help, I really appreciate it and the reason I ask so many questions because I would like to develop myself always – Szabolcs Magyar Jul 05 '19 at 11:48