简体   繁体   中英

Post form values based on user selection in PHP

I need to make a form where users can insert products in a database. The database has columns "Name", "SKU", "Type", "Attributes". The form has fields "Name", "SKU", "Price" and a select box "Type" with three options - "Furniture", "Dvd-disc" and "Book".

Additional form fields are show based on what user chooses in the "Type" selection. For example, if the user chooses "Furniture" from the select box, then three fields, "Height", "Width", "Length", appear. If he chooses "Books", a "Weight" field appears, and if he chooses "DVD-disc", the field "Size" appears.

The jQuery funcion to hide/show required fields is not implemented yet, so don't mind that.

EDIT: When I post, for example, the type Disc and Size 700, and do "var_dump($_POST);" I get:

array(8) { ["sku"]=> string(8) "BT944RUR" ["name"]=> string(22) "Third insert from page" ["price"]=> string(5) "56.25" ["type"]=> string(8) "DVD-disc" ["size"]=> string(3) "700" ["dimensions"]=> array(3) { ["height"]=> string(0) "" ["width"]=> string(0) "" ["length"]=> string(0) "" } ["weight"]=> string(0) "" ["submit"]=> string(6) "Submit" }

It collects the Size value from the form but doesn't pass it further.

HTML form:

<form action="" method="post">
    <div class="form-group">
        <label for="sku">SKU</label>
        <input type="text" class="form-control" id="sku" name="sku">
    </div>
    <div class="form-group">
        <label for="name">Name</label>
        <input type="text" class="form-control" id="name" name="name">
    </div>
    <div class="form-group">
        <label for="price">Price</label>
        <input type="text" class="form-control" id="price" name="price">
    </div>
    <div class="form-group">
        <label for="type">Disabled select menu</label>
        <select id="type" name="type" class="form-control">
            <option></option>
            <option>DVD-disc</option>
            <option>Book</option>
            <option>Furniture</option>
        </select>
    </div>
    <div class="form-group">
        <label for="size">Size</label>
        <input type="text" class="form-control" id="size" name="size">
    </div>
    <div class="form-group">
        <label for="dimensions[height]">Height</label>
        <input type="text" class="form-control" id="height" name="dimensions[height]">
    </div>
    <div class="form-group">
        <label for="dimensions[width]">Width</label>
        <input type="text" class="form-control" id="width" name="dimensions[width]">
    </div>
    <div class="form-group">
        <label for="dimensions[length]">Length</label>
        <input type="text" class="form-control" id="length" name="dimensions[length]">
    </div>
    <div class="form-group">
        <label for="weight">Weight</label>
        <input type="text" class="form-control" id="weight" name="weight">
    </div>
    <input type="submit" name="submit" id="submit" class="btn btn-default">
</form>

PHP code so far (to pass the variables to the insert):

if(isset($_POST['submit'])) {
    $sku = $_POST['sku'];
    $name = $_POST['name'];
    $price = $_POST['price'];
    $type = $_POST['type'];
    $attributes = '';

    if(isset($_POST['dimensions']) && !empty($_POST['dimensions'])) {
        $attributes = implode(' x ', $_POST['dimensions']);
    }
    else if(isset($_POST['weight']) && !empty($_POST['weight'])) {
        $attributes = $_POST['weight'];
    }
    else if(isset($_POST['length']) && !empty($_POST['length'])) {
        $attributes = $_POST['length'];
    }

    $fields = [
        'SKU'=>$sku,
        'Name'=>$name,
        'Price'=>$price,
        'Type'=>$type,
        'Attributes'=>$attributes
    ];

    $product = new Products();
    $product->insert($fields);
}

Insert function (in a different file):

    public function insert($fields) {

        $implodeColumns = implode(', ', array_keys($fields));
        $implodeValues = implode(", :", array_keys($fields));

        $sql = "INSERT INTO products ($implodeColumns) VALUES (:".$implodeValues.")";

        $result = $this->connect()->prepare($sql);

        foreach ($fields as $key => $value) {
            $result->bindValue(':'.$key, $value);
        }

        $resultExec = $result->execute();

        if($resultExec) {
            header('Location: index.php');
        }
    }

I think the if statements are wrong. I can pass the dimensions to the database in such a way but if I try to send size or weight it just passes epmty values with two "x" between them.

And additional question: can I achieve this without using conditional statements? I'm open to different approaches.

A few notes.

Since you're only interested if the user has submitted values, you can simplify your if statements:

if($_POST['dimensions']) {
    $attributes = implode(' x ', $_POST['dimensions']);
}
else if($_POST['weight']) {
    $attributes = $_POST['weight'];
}
else if($_POST['length']) {
    $attributes = $_POST['length'];
}

I do however wonder why you don't record height/width/length separately in the database?

If I were you, I would update my database table to reflect what you're collecting from your users (or vice versa), and do a straight insert of all columns every time a user submits a form, even if some of the fields values have been submitted empty. This has the added bonus of simplifying your life later on if/when you decide to add or remove columns in the database or front-end form.

And finally, please, please either clean the user input, or use prepared SQL statements to avoid SQL injection attacks .

The problem is your first if :

if(isset($_POST['dimensions']) && !empty($_POST['dimensions'])) {

As seen in your HTML, dimension is an array of inputs: length, height, width. This means the variable will never be empty.

$dimensions = [
    'length' => '',
    'width'  => '',
    'heigth' => '',
];

echo empty($dimensions) ? 'dimensions is empty': 'dimensions is not empty'; //output: dimensions is not empty

As solution would to "clean" out nullable values from your array before testing if its empty. To do this, you can resort to array_filter

echo empty(array_filter($dimensions)) ? 'dimensions is empty': 'dimensions is not empty'; //output: dimensions is empty

demo

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