Viewed   73 times

I am learning PDO and i am getting very confused, I have this piece of code below and all looks right to me however I'm getting this error code and I don't know what I have to do to fix it, please help me:

<?php
$hostname='localhost';
$username='root';
$password='';

try {
    $dbh = new PDO("mysql:host=$hostname;dbname=stickercollections",$username,$password);
    echo 'Connected to Database<br/>';
    
    $sql = "SELECT * FROM stickercollections";
foreach ($dbh->query($sql) as $row)
    {
    echo $row["collection_brand"] ." - ". $row["collection_year"] ."<br/>";
    }
    
    
    $dbh = null;
    }
catch(PDOException $e)
    {
    echo $e->getMessage();
    }
?> 

Error Code

Invalid argument supplied for foreach() in /Applications/XAMPP/xamppfiles/htdocs/GOTSWAPMAIN/index.php on line 11

 Answers

2

Try to increase error mode:

<?php
$hostname='localhost';
$username='root';
$password='';

try {
    $dbh = new PDO("mysql:host=$hostname;dbname=stickercollections",$username,$password);

    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // <== add this line
    echo 'Connected to Database<br/>';

    $sql = "SELECT * FROM stickercollections";
foreach ($dbh->query($sql) as $row)
    {
    echo $row["collection_brand"] ." - ". $row["collection_year"] ."<br/>";
    }


    $dbh = null;
    }
catch(PDOException $e)
    {
    echo $e->getMessage();
    }
?> 

EDIT: pdo.error-handling says, you can alternatively use pdo.errorcode and pdostatement.errorcode (or like) to get more info, but I think throw exception is better way to handle bad connections, not resolved hosts etc.

Wednesday, September 21, 2022
4

Personally I find this to be the most clean - not sure if it's the most efficient, mind!

if (is_array($values) || is_object($values))
{
    foreach ($values as $value)
    {
        ...
    }
}

The reason for my preference is it doesn't allocate an empty array when you've got nothing to begin with anyway.

Monday, September 19, 2022
4

Just modify this line

foreach ($query->result() as $row) {

To

foreach ((array)$query->result() as $row) {

Tuesday, September 20, 2022
 
2

You have to specify fetching mode

$q->fetchAll(PDO::FETCH_ASSOC);
Wednesday, December 7, 2022
 
2

When you prepare the $sql_data array, you need to prefix the parameter name with a colon:

array('queryString' => $value);

should be:

array(':queryString' => $value);

In your first SELECT, you have AGINST instead of AGAINST.

Your second SELECT appears to be missing a table name after FROM, and a WHERE clause. The LIKE parameters are also not correctly formatted. It should be something like:

sql = "SELECT * FROM ".$db_prefix."_base WHERE article_title_".$lang." LIKE '%:queryString%' OR aricle_text_".$lang." LIKE '%:queryString%'";

Update 1 >>

For both SELECT statements, you need unique identifiers for each parameter, and the LIKE wildcards should be placed in the value, not the statement. So your second statement should look like this:

sql = "SELECT * FROM ".$db_prefix."_base WHERE article_title_".$lang." LIKE :queryString OR aricle_text_".$lang." LIKE :queryString2";

Note queryString1 and queryString2, without quotes or % wildcards. You then need to update your array too:

$sql_data = array(':queryString1' => "%$value%", ':queryString2' => "%$value%");

See the Parameters section of PDOStatement->execute for details on using multiple parameters with the same value. Because of this, I tend to use question marks as placeholders, instead of named parameters. I find it simpler and neater, but it's a matter of choice. For example:

sql = "SELECT * FROM ".$db_prefix."_base WHERE article_title_".$lang." LIKE ? OR aricle_text_".$lang." LIKE ?";

$sql_data = array("%$value%", "%$value%");

<< End of Update 1

I'm not sure what the second SELECT is for, as I would have thought that if the first SELECT didn't find the query value, the second wouldn't find it either. But I've not done much with MySQL full text searches, so I might be missing something.

Anyway, you really need to check the SQL, and any errors, carefully. You can get error information by printing the results of PDOStatement->errorCode:

$sth->execute($sql_data);
$arr = $sth->errorInfo();
print_r($arr);

Update 2 >>

Another point worth mentioning: make sure that when you interpolate variables into your SQL statement, that you only use trusted data. That is, don't allow user supplied data to be used for table or column names. It's great that you are using prepared statements, but these only protect parameters, not SQL keywords, table names and column names. So:

"SELECT * FROM ".$db_prefix."_base"

...is using a variable as part of the table name. Make very sure that this variable contains trusted data. If it comes from user input, check it against a whitelist first.

<< End of Update 1

You should read the MySQL Full-Text Search Functions, and the String Comparison Functions. You need to learn how to construct basic SQL statements, or else writing even a simple search engine will prove extremely difficult.

There are plenty of PDO examples on the PHP site too. You could start with the documentation for PDOStatement->execute, which contains some examples of how to use the function.

If you have access to the MySQL CLI, or even PHPMyAdmin, you can try out your SQL without all the PHP confusing things. If you are going to be doing any database development work as part of your PHP application, you will find being able to test SQL independently of PHP a great help.

Friday, December 9, 2022
 
2

The variable you supply to the foreach loop has to be an array. You can skip the foreach if the value of the variable supplied is not an array with the solution below.

<?php if(is_array($result)): ?>
<?php foreach($result as $row):?>  
<h3><? echo $row->title; ?></h3>  
<p><? echo $row->text; ?></p>  
<?php endforeach;?>  
<?php endif; ?>
Tuesday, September 27, 2022
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :