bcosca / fatfree

A powerful yet easy-to-use PHP micro-framework designed to help you build dynamic and robust Web applications - fast!
2.66k stars 446 forks source link

SQL Mapper find() returns only 1 match with 'IN' #1240

Closed abcpremium closed 3 years ago

abcpremium commented 3 years ago

Hey, I tried to get the following SQL statement to work:

SELECT * FROM mytable WHERE record_id IN (1, 34, 69);

I did this with the following call ($orderModel extends \DB\SQL\Mapper):

$recordIds = [1, 34, 69];
$filterValues = implode(", ", $recordIds);
$filter = ["record_id IN ( ? )", $filterValues];
$records = $this->_orderModel->find($filter);

The variable $records should hold 3 entries, since all these ids exist. However, only the first one get returned. If I do it the hard way, saying:

$recordIds = [1, 34, 69];
$filterValues = implode(", ", $recordIds);
$records = $this->_db->exec("SELECT * FROM orders WHERE record_id IN (" . filterValues . ")");

This works, it returns all 3 entries. However I need to get these results using the find() order select() method from the FatFree Mapper.

Is this a bug? Or what can I do to get all 3 entries by using one of the mapper functions?

geniuswebtools commented 3 years ago

This is not a bug. You need to escape each element in the array.

So something like this: (untested code) $filterValues = trim(str_repeat('?,', count($recordIds)), ','); $filter = ["record_id IN (" . $filterValues . ")", $recordIds];

... so you want something like this in the end: $filter = ["record_id IN (?,?,?)", $recordIds];

ikkez commented 3 years ago

The correct syntax is $model->find( [ 'record_id IN ( ?, ?, ?)', 1, 34 , 69]);, because you cannot simply pass an array as pdo parameter.

If you'd like something more dynamic, based on the array size, you have to construct it yourself, i.e.:

$recordIds = [1, 34, 69];
$records = $model->find(array_merge(['record_id IN ('.str_repeat('?,', count($recordIds) - 1).'?)'], $recordIds));

A more convenient way, where you can pass an array for IN query is build into f3-cortex... however it's a more fat solution to use then.