I have a third-party package method that adds rows to a custom on-screen keyboard like this:
$keyboard = InlineKeyboardMarkup::make();
$keyboard->addRow(
InlineKeyboardButton::make('Button 1', callback_data: '1'),
InlineKeyboardButton::make('Button 2', callback_data: '2')
);
I have an array of letters for which I’m trying to create buttons on the on-screen keyboard, but also don’t want a single letter per row, so this is what I tried:
$letters; // ['a', 'b', 'd' ...]
$rowItems = 5;
$currentItem = 0;
$buttons = [];
for ($i = 0; $i < count($letters); $i++) {
if ($currentItem === $rowItems || $i === (count($letters) - 1)) {
$keyboard->addRow((object)$buttons);
$buttons = [];
$currentItem = 0;
} else {
$buttons[] = InlineKeyboardButton::make($letters[$i], callback_data: $letters[$i]);
$currentItem++;
}
}
This fails because it says it can’t find an expected property in the InlineKeyboardButton object. How can I make the contents of addRow() the same as in the first example above, but dynamically based on varying inputs?
2
Answers
You have two problems:
$keyboard->addRow((object)$buttons);
You can also skip checking the "are we at the end yet?" condition on every loop and replace it with a "was there anything left over?" check following the loop.
Also, unless you are absolutely certain that you need a
for()
loop will at the least work the same with less boilerplate, if not avoiding problems like non-sequential or non-numeric arrays.Also, checking
$x == $some_bound
in a bounded loop works only when$x
increments exactly as expected. Checking$x >= $some_bound
ensures that there is not accidentally an infinite loop if$x
does something unexpected.Consolidated into code:
I’d suggest you make use of PHP’s associative array capability. Since you need 2 parameters, this should work very well.
I managed to locate the telegram-bot class you are using, so I’m reasonably confident this code will work for you.
Your configuration array would be in this form:
You can then use array_map to process the array and build your array of buttons. The lambda(anonymous function) will create an array of keyboard button objects that you pass to the addRow method of the keyboard class, providing a solution to your question as posed.
This is similar to sammitch’s answer, only using array_map and a lambda.