PHP PDO fetch returns false or empty array based on condition

This is something I am trying to figure out, but won’t working…
In database I have everything I should have, and now I need to fetch values from database by id. I have cart database with several tables and inserted values in it, so in my model I am supposed to return data to controller and basically display to view. It returns empty array or just throws false depends what I am checking for.

Code:

Namespace App\Model;

use App\Core\Database;
use PDO;

Class Products
{
    public function getProductsById($id)
   {
       $sql = "SELECT * FROM products WHERE id = :id";
       $stmt = Database::getInstance()->prepare($sql);
       $stmt->bindParam(':id', $id);
       $stmt->execute();
       $products = $stmt->fetchAll(PDO::FETCH_ASSOC); 
       return $products(); // array (size=0) empty
   }
}

Note: I tried pretty much everything. I know this is kinda dummy question, and this should work, especially because I have here couple of queries with joins, but this is driving me crazy. Any help would be great.

Copy/paste anomaly or your actual code?

return $products();

Not clear what you are actually asking. Seems a bit strange that you would have multiple products with the same id.

1 Like

No, not c/p, I rarely copy and paste code.

No, every product has its own id, basically just want to display every product based on it’s id…

The point being is that the line I showed is invalid code.

If you want to return the actual product (or null if not found) then:

return count($products) ? $products[0] : null;

will do the trick.

and change the method name to: getProductById

Thanks, it returns null, I tried that.

The problem is I don’t know what am I doing wrong here.

Thumbs up for changing method name :smiley:

Okay. So it is not returning an expected row?

Typically you would specify a data type when using bindParam:

$stmt->bindParam(':id', $id, PDO::PARAM_INT);

Though I don’t that is the actual problem. Are you sure you are connecting to the database? Do you have exceptions being thrown? If you try connecting with the wrong password do you get an error?

It’s actually a bit unusual to use bindParam. Just passing an array to execute is more common:

$stmt->execute([':id' => $id]);

Answer to your first question is no.

I am pretty sure that I connected properly to database cuz I have like a 15 queries in whole project with joins and stuff and everything is working fine until now.

So going back to return $products(); for a moment, was this your actual code and it did not toss an error like Uncaught Error: Function name must be a string.

Are you sure you are actually calling Products::getProductById? Just looking for possibilities.

No, there are no erros at all. Yes 100% sure! I went through the code several times and run code through debugger in PhpStorm. I tried to run this query in phpmyadmin to just see maybe there is mistake, but nothing.

So no errors when you executed return $products();? That implies that you don’t have error reporting turned on. Add

error_reporting(E_ALL);

to the relevant file.

Still nothing

I’m pretty much out of ideas. You should be getting an error when $products() executes. So either you still have errors suppressed or the line is never being reached. I’m guessing the problem is elsewhere in your code but hopefully someone else will stop by and help.

Just for grins, try copying this code into a file, adjust the connection and then executing from the command line:

<?php

error_reporting(E_ALL);

$options = [
    PDO:: ATTR_ERRMODE            => PDO:: ERRMODE_EXCEPTION,
    PDO:: ATTR_DEFAULT_FETCH_MODE => PDO:: FETCH_ASSOC,
    PDO:: ATTR_EMULATE_PREPARES   => false,
];
$db = new PDO("mysql:host=localhost;dbname=play;charset=utf8", "user", "pass", $options);

class Products
{
    public function find($id)
    {
        global $db;

        $stmt = $db->prepare('SELECT * FROM products WHERE id = :id');
        $stmt->execute([':id' => $id]);
        $rows = $stmt->fetchAll();
        var_dump($rows);
        //return $rows();
        return count($rows) ? $rows[0] : null;
    }
}
$products = new Products();
$product = $products->find(1);
var_dump($product);

Try it with and without the return $rows() line to see the error I keep talking about.

1 Like

This still isn’t making sense to me.
The query looks like it is made to select just one single product (by the ID).
But everything else…

You call it products, as if you expect multiple products, not one.
You use fetchAll(), as if you expect multiple rows.
And in your description, quoted above, you say “every product”.
All this sounds like you expect multiple products, but a query selecting by a unique ID can only ever select just one row.

Can you clarify whether you want to select just one product, or several?

What are you passing into the method as $id? A single ID int?

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.