The php/html file I am working on is laid out in this way.

<?php
  // connect to DB $connection
?>

html
html
html

<?php
  foreach($connection-query($sql) as $row)
    do stuff
?>

I'm getting the error 'Invalid argument supplied for foreach()' when I run this page. Can I not break out of the php and go into html and then come back to my php using the $connection variable created in the upper php code? Or once I break out with ?> is that it, all variable can not be picked back up again futher down in the page?
I can't think of another reason because I have used that exact foreach loop in another file and it worked fine.

Sure is not $connection->query($sql) with -> instead of -? It seems you're calling a method, or an anonymous function, I think the former.

In the latter case, then in PHP you cannot use the dash in the variable name, unless you use brakets, for example:

${'connection-query'} = function() { return 'hello'; };
print ${'connection-query'}();

Or once I break out with ?> is that it, all variable can not be picked back up again futher down in the page?

What is declared in the top of the file is accessible in all the rest of the file, unless you unset the variable or rewrite it with something else.

This is the code I wrote at first and it's working with any problems. But when tried the same thing with my newer program I'm getting the error 'Invalid argument supplied for foreach()'. Again the program below works just fine. Any ideas?

<?php
    // open a DB connectiong
    $dbn = 'mysql:dbname=popcount;host=127.0.0.1';
    $user = 'user';
    $password = 'password';

    try
    {
        $connection = new PDO($dbn, $user, $password);
    }
    catch (PDOException $e)
    {
        echo "Connection failed: " . $e->getMessage();
    }
?>

<html>
    <form method='post' action="">
        Please Enter Customer id# <input name='id' type='text' /> <input type='submit' />
    </form>
</html>

<?php
        $id = $_POST['id'];
        echo $id;

        $sql = "SELECT full_name FROM customers WHERE id# =".$id;

        foreach($connection->query($sql) as $row)
        {
            print $row['full_name']."\n";
        }
?>

The number sign # acts like a comment in MySQL, in your case it will affect the query by returning all the rows instead of selecting by id. But this should not return the Invalid argument supplied for foreach() error, it seems that your query returned boolean FALSE.

To understand what is going on, use a try/catch block and exceptions. For example:

$connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

try {
    $stmt = $connection->prepare("SELECT full_name FROM customers where id = ?");
    $stmt->execute(array($_POST['id']));
    $row = $stmt->fetch(PDO::FETCH_ASSOC);
}
catch(Exception $e)
{
    print 'Error Code: ' . $e->getCode() . PHP_EOL;
    print 'Error Message: ' . $e->getMessage() . PHP_EOL;
    die();
}

print $row['full_name'];

Note: using die() and printing error messages directly in page is good in development stage, while in production you should append all error codes and messages to the error log file and return a simple message, without details.

Documentation:

Thanks I'll give that a try. I'm not actually using a '#' in my code. I just didn't want to post the actualy code because it's for my State's correctional DEPT. I just didn't understand why the foreach loop worked with that same argument in my test code but not in my development file.

Are you using the same PHP version for both your test & development? What did you get when you echo $id;? Do you have the database set up the same way as in test?

The error states that you are passing in something which is not an array to foreach. If the query() fails, it will return False which is not an array (see Source).

In reality both code files are using the same database and table, same version of php on the same computer.

GOOD

$sql = "SELECT full_name FROM inmate_board WHERE tdoc_number =".$tdoc;

        foreach($connection->query($sql) as $row)

/GOOD

BAD->PHP Warning: Invalid argument supplied for foreach()

    $sql = "SELECT full_name, tdoc_number, race, facility FROM inmate_board WHERE type = COURT";

    foreach($connection->query($sql) as $row)

/BAD

You have to set quotes around the value you want to search, otherwise COURT will be interpreted as a column name. So:

$sql = "SELECT full_name, tdoc_number, race, facility FROM inmate_board WHERE type = 'COURT'";

By using exceptions and the try/catch block, you would have seen the error:

Error Code: 42S22
Error Message: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'COURT' in 'where clause'

Using try/except was on my todo list but I don't have any experience using error/exception handling. Thanks cereal it's mostly working now.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.