qadenza
qadenza

Reputation: 9293

shorter way to collect and send data without a form

I have some (15) input, select, and textarea tags on page - without a form
need to collect their values and insert them into a database
this code works fine, but I hope there is a way to short it
on client side - maybe some kind of serialize
on server side - especially on execute statement - maybe some kind of loop

$('#btn_send').on('click', function(){
    let obj = {};
    $('input, select, textarea').each(function(){
        let a = $(this).attr('name');
        obj[a] = $(this).val();
    });
    let str = JSON.stringify(obj);
    $.post('reg.php', {fn: 'btn_send', args: [str]}, function(data){
        console.log(data);
    });
});

reg.php

function btn_send($str){
    global $db;
    $obj = json_decode($str);
    // here are table columns
    $a = "name,birth,gender,city,state,gmail,fb,tw,web,phone,occ,food,note,uname,pass";
    $b = ':a' . str_replace(',', ', :a', $a);
    $sq = "insert into members ($a) values ($b)";
    $st = $db->prepare($sq);
    $st->execute([
        ":aname" => $obj->name,
        ":agender" => $obj->gender,
        //... and so on - 15 items
    ]);
    echo 'success';
}

Upvotes: 0

Views: 73

Answers (2)

SSpoke
SSpoke

Reputation: 5836

Something I made not sure if it even compiles, just was bored this is how I would do the 15 items or so part.

function btn_send($str){
    global $db;
    $obj = json_decode($str);
    // here are table columns
    $a = "name,birth,gender,city,state,gmail,fb,tw,web,phone,occ,food,note,uname,pass";
    $b = ':a' . str_replace(',', ', :a', $a);
    $sq = "insert into members ($a) values ($b)";
    $st = $db->prepare($sq);
    $sqlArray = array();
    foreach($obj as $key => $value) {
        $sqlArray[]= array(":a".$key => $value);
    }
    $st->execute($sqlArray);

    echo 'success';
}

Edit: I looked at Nick's answer it seems you don't even need to do all the hard stuff I did, you can just pass $obj wow they made it so easy now

Upvotes: 1

Nick
Nick

Reputation: 147216

Based on your code sample, it looks like the elements of your object have the same names as the columns in your table. In that case, you can simplify your code by converting the incoming JSON to an array rather than an object and utilising the fact that PDOStatement::execute allows the array keys to not include the : in the names:

$obj = json_decode($str, true);
// here are table columns
$cols = array_keys($obj);
$a = implode(',', $cols);
$b = ':a' . str_replace(',', ', :a', $a);
$sq = "insert into members ($a) values ($b)";
$st = $db->prepare($sq);
$st->execute($obj);

Should the behaviour of execute change in the future, you can make an array with the keys preceded with : using array_combine and array_map:

array_combine(array_map(function ($k) { return ":$k"; }, $cols), $obj)

You would then pass this array to execute in place of $obj.

Upvotes: 1

Related Questions