How to fix Warning: Invalid argument supplied for foreach()


#1

 ini_set('display_errors', '1');
 ini_set('display_startup_errors', '1');
 error_reporting(E_ALL);
 
 include_once 'core/init.php'; 

 require 'common.php'; //Escapes HTML for output


 if (isset($_POST['submit'])) { 

	try{
	      $this->dbh = new PDO($dsn, $this->user, $this->pass, $options);

	$user = [
	      "id"        => $_POST['id'],
	      "username"  => $_POST['username'],
	      "email"     => $_POST['email'],
	      "join_date" => $_POST['join_date']
	    ];

   $DB->query ('UPDATE users 
   			SET id = :id, 
   			username = :username, 
            email = :email, 
            join_date = :join_date
   			WHERE id = :id');

	$DB->execute();

	}
	catch(PDOException $e){

		echo $this->error = $e->getMessage();
	 }

 }

	if (isset($_GET['id'])) {

		try{
	         $this->dbh = new PDO($dsn, $this->user, $this->pass, $options);

	         $id = $_GET['id'];

	         $DB->query('SELECT * FROM users WHERE id = :id');

	         $DB->bind(':id', $id);

	         $DB->execute();

	         $result=$DB->resultset();

	        // Catch any errors
	   		}
	   		catch(PDOException $e){

	           echo $this->error = $e->getMessage();

	        }
	    }

	    
?>

<?php include "templates/header.php"; ?>


<?php if (isset($_POST['submit']) && $DB) : ?>

	<blockquote><?php echo escape($_POST['username']); ?> successfully updated.</blockquote>

<?php endif; ?>

<h2>Edit a user</h2>

<form method="post">

    <?php foreach ($user as $key => $value) : ?>

      <label for="<?php echo $key; ?>"><?php echo ucfirst($key); ?></label>

	    <input type="text" name="<?php echo $key; ?>" id="<?php echo $key; ?>" value="<?php echo escape($value); ?>" <?php echo ($key === 'id' ? 'readonly' : null); ?> >

    <?php endforeach; ?> 

    <input type="submit" name="submit" value="Submit">
</form>

<a href="http://localhost/form/home.php">Back to home</a>

<?php include "templates/footer.php"; ?>

#2

Try this:


<form method="post">
  <?php if( isset($user) && is_array($user) ): ?>
    <?php foreach ($user as $key => $value) : ?>
      <label for="<?php echo $key; ?>"><?php echo ucfirst($key); ?></label>
      <input type="text" name="<?php echo $key; ?>" id="<?php echo $key; ?>" value="<?php echo escape($value); ?>" <?php echo ($key === 'id' ? 'readonly' : null); ?> >
    <?php endforeach; ?> 
    <input type="submit" name="submit" value="Submit">
  <?php 
    else: 
      echo 'Problem with user???' ; 
    endif;
  ?>  
</form>
...

#3

The error normally appears when the variable that should contain an array that the foreach loop will work on doesn’t contain an array. At any point where you’re going to load stuff into an array that a foreach will work with, set the array up first, so say the array is just a list of names you’d do:

$name=array();

That would set up $name as an empty array, so that if nothing is loaded into it, a foreach loop that will be working with will actually see an array, even if that array is empty


#4

Thanks it helped me thou’ when i run it… echo problem with user???;


#5

Well, that follows - in your original code you used $user without checking whether it exists or not, now the code is checking for that, seeing that it does not, and showing a message rather than a warning.


#6

The conditional logic is

if there is a $user variable
and the $user variable is an array
// do stuff
else
( there is no $user variable
or the $user variable is not an array )
// echo ‘Problem with user???’ ;

By looking at where the $user variable is coming from before it gets to the conditional you should be able to find the problem.

As previously posted, one way to approach this is to make sure the variable is defined as an empty array, populate the array later on, then access the array. If for whatever reason the array did not get populated the isset and is_array will be truthy. The foreach will not error, but because the array is empty there will be no “each” for it to do anything with.

This may or may not be a suitable solution. What control structure is used depends on what is wanted to happen in different conditions.

The more precisely you can map out all possible code flow the better you can avoid errors.


#7

Assuming the original code is accurate then it’s pretty clear that $user is not being set at all for the GET request.


#8

Thanks I get the point…