Skip to content
Advertisement

Invalid argument supplied for foreach() when hitting the URL

I have two pages as of now called index.php and checkout.php.

In the index.php page, I have 2 checkboxes and 4 radio buttons.

What I am doing is, When the user checked the checkbox and radio buttons and clicks on the submit button then I am sending the value of checkboxes and radio buttons to the checkout.php page and that values will call my query to display the output on my checkout page.

I tried to send the data from one page to another page using SESSION and it is working. I am getting the POST data my check out page and I am getting the output of my query as well.

Now my issue is, If I refresh the page then there is no issue but when I hit the URL then I am getting the error

Warning: Invalid argument supplied for foreach() in /home4/test/example/checkout.php on line 70

index.php

<form action="checkout.php" method="post" name="form1">
    <div class="formWrapper">
        <div class="form-group">
            <fieldset>
            <input type="checkbox"  name="fruit[1]"  value="1"><label>Fruit One</label><br />
            <input type="radio"  name="color[1]"  value="1"><label>Black</label>
            <input type="radio"  name="color[1]"  value="2"><label>Yellow</label>
            </fieldset>
        </div>
        <div class="form-group">
            <fieldset>
            <input type="checkbox"  name="fruit[2]"  value="2"><label>Fruit Two</label><br />
            <input type="radio"  name="color[2]"  value="1"><label>Black</label>
            <input type="radio"  name="color[2]"  value="2"><label>Yellow</label>
            </fieldset>
        </div>
        <input type="submit" name="submit" value="Next">
    </div>
</form>

checkout.php

<?php
session_start();
 include('connection.php');
 if(isset($_POST['submit'])){
 $_SESSION['fruits']=$_POST['fruit'];
 $_SESSION['colors']=$_POST['color'];
  
  foreach ($_SESSION['fruits'] as $key => $value) {
  try{
     $sqlquery="SELECT col1,col2, (select demoCol from tbl_colors where c_id=:c_id) as demoColor FROM tbl_mytable WHERE id=:id and is_active=1";
    $stmt = $pdo->prepare($sqlquery);
     $stmt->execute( array(':c_id' => $_SESSION['colors'][$key],':id'=>$_SESSION['fruits'][$key]) );
    $result = $stmt->fetchAll();
     foreach ($result as $row) {?>
        <h3><?php echo $row['col1'];?> <?php echo $row['col2'];?></h3>
        <p><?php echo $row['demoColor'];?></p>
<?php
     }
 }
 catch(PDOException $e) {
  echo "Error: " . $e->getMessage();
  }
}
 }
 ?>

Advertisement

Answer

Looking through your code quickly I think you could modify it a little

<?php

    session_start();
    /*
        `fruit` and `color` MUST be available
        before attempting to assign as any 
        sort of variable - so test here!
    */
    if( isset( 
            $_POST['submit'],
            $_POST['fruit'],
            $_POST['color']
        )){
        
        
        include('connection.php');
        /*
            It is not entirely clear why you would want to assign
            session values directly from POST values when you could
            simply work with the POST values instead.
        */
        $fruits=$_POST['fruit'];
        $colours=$_POST['color'];
        
        /*
            create the sql statement with placeholders
            which are then bound as parameters when the
            statement is executed.
            
            Create the statement once and assign new values
            inside of any loops rather than re-stating it
            on each iteration.
        */
        $sql='select `col1`, `col2`, ( select `democol` from `tbl_colors` where `c_id`=:cid ) as `democolor`
                from `tbl_mytable`
                where `id`=:id and `is_active`=1';
        
        $stmt=$pdo->prepare( $sql );

        
        
        /*
            Process the POSTed variables
            using the $key to access the values
            within the other array ( colours )
        */
        foreach( $fruits as $key => $value ) {
            try{
                if( isset( $colours[ $key ] ) ){
                    $stmt->execute( array(
                        ':cid'  =>  $value,
                        ':id'   =>  $colours[ $key ]
                    ));
                    $result = $stmt->fetchAll();
                    foreach( $result as $row ) {
?>
                    <h3>
                        <?php echo $row['col1'];?>
                        <?php echo $row['col2'];?>
                    </h3>
                    <p><?php echo $row['demoColor'];?></p>
<?php
                    }
                }
            } catch( PDOException $e ) {
                echo "Error: " . $e->getMessage();
            }
        }
    }
?>

Closer inspection suggests that you could probably have just a single SQL query to retrieve all the records by initially processing the POST data and generating suitable strings containing the various IDs in order that you use the IN operator in the sql – such as where id IN (1,2,3) etc – like:

$sql='select `col1`, `col2`, ( select `democol` from `tbl_colors` where `c_id` IN ( :cids ) ) as `democolor`
        from `tbl_mytable`
        where `id` IN ( :ids ) and `is_active`=1';
$stmt=$pdo->prepare( $sql );

$args=array(
    ':cids' =>  implode(',',array_values( $colours ) ),
    ':ids'  =>  implode(',',array_values( $fruits ) )
);

$stmt->execute( $args );

I hope this may be of use – I should stress that none was tested so there could be errors but hope not.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement