-1

I want to submit the values of marks, grade, subject, and name of different students in PHP. While adding the marks the average and grade get automatically calculated in front end using jQuery of each student. But I am having trouble submitting array values through PHP. I tried several options but none of them worked.

<?php 
$con=mysqli_connect('localhost','root','','student');
if($con){
    echo "connected";
}
else{
    echo "not connected";
}

if(isset($_POST['submit'])){
    $stack = array();
    $name=$_POST['name'];
    $roll=$_POST['roll'];
    $class=$_POST['class'];
    $phy=$_POST['phy'];
    $eng=$_POST['eng'];
    $maths=$_POST['maths'];
    $average=$_POST['average'];
    $grade=$_POST['grade'];

    array_push($stack, $name);
    array_push($stack, $roll);
    array_push($stack, $class);
    array_push($stack, $phy);
    array_push($stack, $eng);
    array_push($stack, $maths);
    array_push($stack, $average);
    array_push($stack, $grade);

    ;
    for ($i=0; $i < sizeof($stack); $i++) { 
        foreach ($stack[$i] as $key => $value) {
            $query="INSERT INTO student_detail (id,name,roll,class,phy,eng,maths,avg,grade) VALUES('','$name[$value]','$roll[$value]','$class[$value]','$phy[$value]','$eng[$value]','$maths[$value]','$average[$value]','$grade[$value]')";
        }
    }

    // print_r($stack);
    $result=mysqli_query($con,$query);
    if($result){
        echo "data inserted";
    }
    else{
        echo "data not".mysqli_error($con);
    }

}
?>

<!DOCTYPE html>
<html>

<head>
  <title>Registration</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

  <!-- Latest compiled JavaScript -->
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js"></script>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">

  <!-- jQuery library -->

  <script>
    $(document).ready(function() {
      var s = 0;

      $('.marks').keyup(function() {

        var idx = $(this).attr('id').split('_')[1];

        $(".active .score_" + idx).each(function() {
          var x = $(this).val();
          if (x) {
            s += Number(x);
          } else {
            s += 0;
          }

        });
        // alert(s);
        // alert(s/3);
        $('#average_' + idx).val(s / 3);
        $('#grade_' + idx).val(grade(s / 3));
        s = 0;

      });

      function grade(average) {
        if (average > 90) {
          return 'A';
        } else if (average < 90 && average > 81) {
          return 'B';
        } else {
          return 'C';
        }
      }

    });
  </script>
</head>

<body>
  <div>
    <form action="index.php" method="POST">
      <div class="table-responsive">
        <table class="table table-condensed table-striped">
          <tr>
            <th>Name</th>
            <th>Roll</th>
            <th>Class</th>
            <th>Phy</th>
            <th>Eng</th>
            <th>Maths</th>
            <th>Average</th>
            <th>Grade</th>
          </tr>
          <?php for($i=1;$i<=2;$i++){ ?>
          <tr class="active">
            <td><input type="text" name="name[]" placeholder="Name"></td>
            <td><input type="text" name="roll[]" placeholder="Roll"></td>
            <td><input type="text" name="class[]" placeholder="Class"></td>
            <td><input type="number" name="phy[]" placeholder="Physics" class="marks score_<?php echo ($i);?>" id="marks_<?php echo ($i);?>"></td>
            <td><input type="number" name="eng[]" placeholder="Eng" class="marks score_<?php echo ($i);?>" id="marks_<?php echo ($i);?>"></td>
            <td><input type="number" name="maths[]" placeholder="Maths" class="marks score_<?php echo ($i);?>" id="marks_<?php echo ($i);?>"></td>
            <td><input type="text" name="average[]" placeholder="average" id="average_<?php echo ($i);?>" class="average"></td>
            <td><input type="text" name="grade[]" placeholder="Grade" id="grade_<?php echo ($i);?>" class="grade"></td>
          </tr>
          <?php } ?>

        </table>
      </div>
      <input class="btn btn-primary" type="submit" name="submit" value="Submit">
    </form>
  </div>

</body>

</html>

After editing

<?php 
$con=mysqli_connect('localhost','root','','student');
if($con){
    echo "connected";
}
else{
    echo "not connected";
}

if(isset($_POST['submit'])){
    $stack = array();
    $name=$_POST['name'];
    $roll=$_POST['roll'];
    $class=$_POST['class'];
    $phy=$_POST['phy'];
    $eng=$_POST['eng'];
    $maths=$_POST['maths'];
    $average=$_POST['average'];
    $grade=$_POST['grade'];

    array_push($stack, $name);
    array_push($stack, $roll);
    array_push($stack, $class);
    array_push($stack, $phy);
    array_push($stack, $eng);
    array_push($stack, $maths);
    array_push($stack, $average);
    array_push($stack, $grade);

    ;
    // for ($i=0; $i < sizeof($stack); $i++) { 
    //  foreach ($stack[$i] as $value) {
    //      // $query="INSERT INTO student_detail (id,name,roll,class,phy,eng,maths,avg,grade) VALUES('','$name[$value]','$roll[$value]','$class[$value]','$phy[$value]','$eng[$value]','$maths[$value]','$average[$value]','$grade[$value]')";

    //      // var_dump($stack);
    //  }
    // }
    var_dump($stack);

    // print_r($stack);
    // $result=mysqli_query($con,$query);
    // if($result){
    //  echo "data inserted";
    // }
    // else{
    //  echo "data not".mysqli_error($con);
    // }

}

?> stack variable dumped

reisdev
  • 3,215
  • 2
  • 17
  • 38
  • I believe you have to add the `[]` at the field names in your php code – Ayrton Oct 18 '19 at 15:28
  • @Ayrton brother I did but the value submitted is 0 only for any input – Abhisake Jain Oct 18 '19 at 15:31
  • Please make this verifiable for us. Remove all the extra crud such as the JS, jquery links, DB queries and connections. The problem is with your loops. `$stack` has data in it but you're not accessing it correctly. To verify, please show us the output of `var_dump($stack);`. – waterloomatt Oct 18 '19 at 15:54
  • Try changing `foreach ($stack[$i] as $key => $value) {` to `foreach ($stack[$i] as $value) {`. – waterloomatt Oct 18 '19 at 15:59
  • @waterloomatt you can see the dumped stack variable output by clicking on the stack variable dumped below edited code – Abhisake Jain Oct 18 '19 at 17:28
  • Right. The data is there. Did you try my suggestion directly above your comment? – waterloomatt Oct 18 '19 at 17:35
  • @waterloomatt yes brother but still it didn't worked I know i am doing one silly mistake but unable to figure it out – Abhisake Jain Oct 18 '19 at 17:37
  • @waterloomatt its giving some notice like undefined index in the query part – Abhisake Jain Oct 18 '19 at 17:39
  • Does this answer your question? [How to include a PHP variable inside a MySQL statement](https://stackoverflow.com/questions/7537377/how-to-include-a-php-variable-inside-a-mysql-statement) – Dharman Nov 14 '19 at 21:03

3 Answers3

0

I had to do a similar thing recently (Although I output as JSON but you should be able to get this to work for your SQL)

First I created my form

Eg

<input required type="text" name="customer[contactName]" class="form-control" placeholder="John Doe">

Then I took the POST data and formatted it into an array.

$UIDv4 = Uuid::uuid4();
$rmqMessage = array("GUID"=>$UIDv4,
    "customer"=>array(
        "companyName"=>$_POST['customer']['companyName'],
        "contactName"=>$_POST['customer']['contactName'],
        "contactEmail"=>$_POST['customer']['contactEmail'],
        "contactPhone"=>$_POST['customer']['contactNumber'],
        "billingName"=>$_POST['customer']['billingName'],
        "billingEmail"=>$_POST['customer']['billingEmail'],
        "billingPhone"=>$_POST['customer']['billingPhone'],
        "Address"=>array(
            "Line1"=>$_POST['customer']['Address']['Line1'],
            "Line2"=>$_POST['customer']['Address']['Line2'],
            "City"=>$_POST['customer']['Address']['City'],
            "State"=>$_POST['customer']['Address']['State'],
            "Zip"=>$_POST['customer']['Address']['Zip'],
            "country"=>$_POST['customer']['Address']['country']
        ),
        "appPrefix"=>$_POST['customer']['appurl']
    )
);

Lastly, I converted it to JSON and pushed it to SQL (But you may not need/want to do this unless you are using SQL Server 2016 or something with JSON support)

$provDatabase->query("exec web_pushRequest ?, ?", $UIDv4->toString(),json_encode($rmqMessage));
CloudTheWolf
  • 334
  • 2
  • 10
0

Changing your form's inputs to item[0][name], will give you a dataset that is much easier to work with. Idea taken from: https://stackoverflow.com/a/3314578/296555.

Also, you're wide open to SQL injection attacks by simply injection the user-entered data into your queries. Look into prepared statements.

<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    foreach ($_POST['item'] as $item) {
        // Each `$item` now represents an entire row from your form.
        // And you can access individual cells with $item['name'] or $item['average'] to use in your SQL.
        var_dump($item);
    }
}
?>  

<form method="post">
    <table class="table table-condensed table-striped">
        <tr>
            <th>Name</th>
            <th>Roll</th>
            <th>Class</th>
            <th>Phy</th>
            <th>Eng</th>
            <th>Maths</th>
            <th>Average</th>
            <th>Grade</th>
        </tr>

        <?php for ($i = 1; $i <= 2; $i++) { ?>
            <tr class="active">
                <td><input type="text" name="item[<?php echo $i; ?>][name]" placeholder="Name"></td>
                <td><input type="text" name="item[<?php echo $i; ?>][roll]" placeholder="Roll"></td>
                <td><input type="text" name="item[<?php echo $i; ?>][class]" placeholder="Class"></td>
                <td><input type="number" name="item[<?php echo $i; ?>][phy]" placeholder="Physics"></td>
                <td><input type="number" name="item[<?php echo $i; ?>][eng]" placeholder="Eng"></td>
                <td><input type="number" name="item[<?php echo $i; ?>][maths]" placeholder="Maths"></td>
                <td><input type="text" name="item[<?php echo $i; ?>][average]" placeholder="average"></td>
                <td><input type="text" name="item[<?php echo $i; ?>][grade]" placeholder="Grade"></td>
            </tr>
        <?php } ?>

    </table>

    <input class="btn btn-primary" type="submit" name="submit" value="Submit">
</form>

Sample output

array (size=8)
  'name' => string 'Matt' (length=4)
  'roll' => string 'Manager' (length=7)
  'class' => string '' (length=0)
  'phy' => string '' (length=0)
  'eng' => string '' (length=0)
  'maths' => string '' (length=0)
  'average' => string '' (length=0)
  'grade' => string '' (length=0)

/var/www/html/public/psft/apply/index2.php:6:
array (size=8)
  'name' => string 'John' (length=4)
  'roll' => string 'Programmer' (length=10)
  'class' => string '' (length=0)
  'phy' => string '' (length=0)
  'eng' => string '' (length=0)
  'maths' => string '' (length=0)
  'average' => string '' (length=0)
  'grade' => string '' (length=0)

Edit

yeah it works but how can I do this my previous way since someone has asked me to that way only as of now.After it works I can work upon security things

The solution has nothing to do with security, other than the suggestion to use prepared statements. My suggestion is to change your input name to make it easier for you to work with. Your current implementation name[], roll[] etc. will create a data structure grouped by element. For example:

array[
    'name' => [
          0 => 'Matt',
          1 => 'John'
    ],
    'roll' => [
         0 => 'Manager',
         1 => 'Programmer'
    ]
]

I think you'll see what the problem is with that. It is very difficult to work with because you need to access a single element from each subarray. You could massage it to get it into a normalized format that you can use to build a query. Something like:

$result = array();
foreach ($_POST as $key => $data) {
    if (is_array($data)) {
        foreach ($data as $offset => $value) {
            if (isset($result[$offset])) {
                $result[$offset][$key] = $value;
            } else {
                $result[$offset] = array($key => $value);
            }
        }
    }
}

That will give you:

array[
    [
        'name' => 'Matt',
        'roll' => 'Manager'
    ],
    [
        'name' => 'John',
        'roll' => 'Programmer'
    ]
]

Which is the same format as my original solution. But it has cost you 2 additional loops and extra code to maintain. I'll leave the decision up to you about which one to go with.

waterloomatt
  • 3,662
  • 1
  • 19
  • 25
  • yeah it works but how can I do this my previous way since someone has asked me to that way only as of now.After it works I can work upon security things – Abhisake Jain Oct 19 '19 at 03:50
-1
<?php 
$con=mysqli_connect('localhost','root','','student');
if($con){
    echo "connected";
}
else{
    echo "not connected";
}

if(isset($_POST['submit'])){
    $stack = array();
    $name=$_POST['name'];
    $roll=$_POST['roll'];
    $class=$_POST['class'];
    $phy=$_POST['phy'];
    $eng=$_POST['eng'];
    $maths=$_POST['maths'];
    $average=$_POST['average'];
    $grade=$_POST['grade'];

    array_push($stack, $name);
    array_push($stack, $roll);
    array_push($stack, $class);
    array_push($stack, $phy);
    array_push($stack, $eng);
    array_push($stack, $maths);
    array_push($stack, $average);
    array_push($stack, $grade);

    ;
    for ($j=0; $j < sizeof($stack); $j++) { 
        foreach ($stack[$j] as $key=>$value) {
            $query="INSERT INTO student_detail (id,name,roll,class,phy,eng,maths,avg,grade,date) VALUES('','$name[$key]','$roll[$key]','$class[$key]','$phy[$key]','$eng[$key]','$maths[$key]','$average[$key]','$grade[$key]',CURDATE())";
            $result=mysqli_query($con,$query);


    //      // var_dump($stack);
        }
        break;
    }
    // var_dump($stack);

    // print_r($stack);

    if($result){
        echo "data inserted";
    }
    else{
        echo "data not".mysqli_error($con);
    }

}

?>