Bug found, exception when using Nette\Database\Table\Selection::fetchPairs with null parameters
- kasi
- Member | 2
When using
Nette\Database\Table\Selection::fetchPairs(string|int|null $key = null, string|int|null $value = null)
, i expected that the function result will be something like:
array<int, {col1, col2, col3, ...}>
but instead of this, I am getting MemberAccessException, because when null is passed as key to function
Nette/Database/Helpers::toPairs(array $rows, $key = null, $value = null)
function will assign first array key as key variable which is in this case
table
(because ActiveRow keys are
table, data, dataRefreshed
)
- m.brecher
- Generous Backer | 862
@kasi
Hi,
I do not understand the problem in full, but I´m standardly using Selection::fetchPairs() for getting data for form input select, where are data in form of array required. So I typically use it like this:
$selectItems = $this->database->table('tableName')->where(...)->order(...)->fetchPairs('id', 'title');
.....
$form->addSelect('field', 'Caption', $selectItems);
This works without any problems.
The data $selectItems look like this:
[
'2' => 'green', // id => title
'6' => 'yellow',
.....
]
But you may be use the method fetchPairs() in other way, send eventually more code samples in case you will not solve the problem ;).
- m.brecher
- Generous Backer | 862
@kasi
i expected that the function result will be something like: array<int, {col1, col2, col3, …}>
No, I dont think so, as the name of method says the result is simple associative php array like array<col1, col2> the pair means pair of columns col1 + col2
To get result like you expect, you have to use another method Selection::fetchAssoc() ;)
Last edited by m.brecher (2023-03-09 13:23)
- kasi
- Member | 2
m.brecher wrote:
@kasi
Hi,
I do not understand the problem in full, but I´m standardly using Selection::fetchPairs() for getting data for form input select, where are data in form of array required. So I typically use it like this:
$selectItems = $this->database->table('tableName')->where(...)->order(...)->fetchPairs('id', 'title'); ..... $form->addSelect('field', 'Caption', $selectItems);
This works without any problems.
The data $selectItems look like this:
[ '2' => 'green', // id => title '6' => 'yellow', ..... ]
But you may be use the method fetchPairs() in other way, send eventually more code samples in case you will not solve the problem ;).
So for example if you will have table
id | username | password |
---|---|---|
1 | user1 | hash1 |
2 | user2 | hash2 |
and i want to fetch normal indexed array, i need to write something like this
public function arrayFrom(Nette\Database\Table\Selection $selection):array {
$rows = [];
while ($row = $selection->fetch()) {
$rows[] = iterator_to_array($row->getIterator());
}
return $rows;
}
which will produce following array ->
[
0 => [
'id' => 1,
'username' => user1,
'password' => hash1,
],
1 => [
'id' => 2,
'username' => user2,
'password' => hash2,
],
]
And i think it should work like this if you dont push null parameters to
Nette\Database\Table\Selection::fetchPairs(string|int|null $key = null, string|int|null $value = null)
because when you will write something like this:
$rows = $this->database->table('user')->select('id, username')->fetchAll();
$rowsOnlyData = [
1 => [
'data' => [
'id' => 1,
'username' => 'user1'
]
],
2 => [
'data' => [
'id' => 2,
'username' => 'user2'
]
]
];
$result = Nette\Database\Helpers::toPairs($rowsOnlyData);
then the $result
will be:
[
0 => [
'id' => 1,
'username' => 'user1',
],
1 => [
'id' => 2,
'username' => 'user2',
],
]
In the other words, if function
Nette\Database\Helpers::toPairs(array $rows, $key = null, $value = null)
does not get parameters $key
and $value
it will
take it from array_keys.
I think, it is confusing. Function
Nette\Database\Table\Selection::fetchPairs(string|int|null $key = null, string|int|null $value = null)
should not has null values, or may be customized in working way.
- m.brecher
- Generous Backer | 862
Hi,
now I understand in full your post. You complain, that
Nette\Database\Helpers::toPairs()
works in a different way than
Nette\Database\Table\Selection::fetchPairs()
.
I havent seen yet Nette\Database\Helpers and found it only in api documentation:
https://api.nette.org/…Helpers.html
but not in the standard documentation https://doc.nette.org/…ase/explorer
In my opinion Nette\Database\Helpers are not designed for public using, but is merely an internal package for another Nette packages.
You need not Nette\Database\Helpers, everything you need in data manipulation you'll find in standard documentation.
You are right that Selection::fetchPairs()
throws exception if
you call it with no parameters, but such a call hase no sence. And
Nette\Database\Helpers nobody use, or at least it is not intention to be used
publically.
Look how Selection::fetchPairs() works:
$table = $this->database->table('test');
$table->fetchPairs(key: 'id', value: 'name'); // [0 => 'Karel', 1 => 'Josef']
$table->fetchPairs(key: 'id'); // [1 => ActiveRow, 2 => ActiveRow]
$table->fetchPairs(value: 'name');// [0 => 'Karel', 1 => 'Josef']
$table->fetchPairs(); // Exception: Cannot read an undeclared column
$table->fetchAssoc('id'); // [1 => array, 2 => array]
So any type of output data you need you can get it. And call $table->fetchPairs() does not make sense.
Last edited by m.brecher (2023-03-11 13:51)