在PHP中创建对象的对象

zi8p0yeb  于 2023-06-04  发布在  PHP
关注(0)|答案(2)|浏览(110)

我有一个第三方包方法,可以像这样向自定义屏幕键盘添加行:

$keyboard = InlineKeyboardMarkup::make();
$keyboard->addRow(
    InlineKeyboardButton::make('Button 1', callback_data: '1'),
    InlineKeyboardButton::make('Button 2', callback_data: '2')
);

我有一个字母数组,我试图在屏幕键盘上创建按钮,但也不希望每行只有一个字母,所以这是我尝试的:

$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++;
  }
}

这会失败,因为它说在InlineKeyboardButton对象中找不到预期的属性。如何使addRow()的内容与上面的第一个示例相同,但动态地基于不同的输入?

yfwxisqw

yfwxisqw1#

你有两个问题:

  • $keyboard->addRow((object)$buttons);
  • 给出你的示例代码,你不需要一个对象,你需要 * 解包数组 *。
  • if/else条件意味着可以添加按钮或行。您需要添加当前行 *,并向新行 * 添加一个按钮。您现有的代码将跳过每第6个[N+1 'th]字母。

你也可以跳过检查“我们结束了吗?”条件,并将其替换为“是否还有剩余?”“检查以下循环。
此外,除非你绝对确定你需要一个for()循环,否则至少可以用更少的样板文件来工作,如果不能避免像非顺序或非数字数组这样的问题的话。

  • 此外 *,在有界循环中检查$x == $some_bound仅在$x按预期增加时才有效。检查$x >= $some_bound可确保在$x执行意外操作时不会意外地出现无限循环。

合并为代码:

foreach($letters as $letter) {
  if ($currentItem >= $rowItems) {
    $keyboard->addRow(...$buttons);
    $buttons = [];
    $currentItem = 0;
  }
  $buttons[] = InlineKeyboardButton::make($letter, callback_data: $letter);
  $currentItem++;
}

if( !empty($buttons) ) {
    $keyboard->addRow(...$buttons);
}
nwlls2ji

nwlls2ji2#

我建议你使用PHP的关联数组功能。因为你需要两个参数,这应该很好。
我设法找到了您正在使用的telegram-bot类,因此我有理由相信这段代码将为您工作。
您的配置数组将采用以下形式:

$keyboardConfig = ['a' => 'a_data', 'b' => 'b_data'];

然后可以使用array_map处理数组并构建按钮数组。lambda(匿名函数)将创建一个键盘按钮对象数组,并将其传递给keyboard类的addRow方法,为您提出的问题提供解决方案。

$keyboardConfig = ['a' => 'a_data', 'b' => 'b_data'];

$buttons = [];
$buttons[] = array_map(
    function($k, $v) {
        return InlineKeyboardButton::make($k)->callbackData($v);
    }, 
    array_keys($keyboardConfig), 
    array_values($keyboardConfig)
);

if (count($buttons) > 0) {
   $keyboard = InlineKeyboardMarkup::make();
   $keyboard->addRow($buttons);
} else {
   // No buttons were created
   // Handle that....
}

这与sammitch的答案类似,只是使用了array_map和lambda。

相关问题