php foreach 循环中的数组

php array in foreach loop

对于我正在构建的 Telegram 机器人,我想 return 动态内联按钮,具体取决于 returned PHP PDO 记录集 Telegram API docs

硬编码一个好的函数代码如下所示。 这已确认有效。它 return 两排按钮。第一行包含两个按钮,第二行包含两个按钮。

$reply  = "Some message to show before the buttons";
$keyb   = array('inline_keyboard' => array(
            array(
                array('text'=>'Link text', 'callback_data'=>'/command'),
                array('text'=>"Link text", 'callback_data'=>'/command')
            ),
            array(
                array('text'=>'Link text', 'callback_data'=>'/command'),
                array('text'=>'Link text', 'callback_data'=>'/command')
            )
          )
        );

$replyMarkup = json_encode($keyb);
sendMessage($chatID, $reply, $replyMarkup);

到目前为止一切顺利。 但是现在我想在给定 PHP 记录集的情况下动态填充这些按钮。

下面 return 需要的按钮,但是 我不知道 如何在两个按钮之后指定一个分界点来创建第二行。在下面的格式中,所有按钮最终都在一行中。即使记录集 returns 5 个结果。

$reply  = "Some message to show before the buttons";

$i=0;
// Loop through all results to create individual buttons
foreach ($stmt as $row) 
{
    $options[] = array('text'=>urlencode($row['title']), 'callback_data'=>'/x');
    $i++;
}

$keyb           = array('inline_keyboard' => array( $options ));
$replyMarkup    = json_encode($keyb);
sendMessage($chatID, $reply, $replyMarkup);

我考虑过使用带模运算符的 if 语句 ($i%2=1),但不知道如何处理定义行的父数组 ()...

...
if($i%2=1)
{ 
    $options[]="array("; // <-- Setting an array as a value will obviously fail
}    
... remaining code

很高兴听到任何可能对我有帮助的想法!

谢谢。

这应该可以解决问题:

<?php
// DUMMY DATA
$stmt = array(
            array('title'=>'Link text1', 'callback_data'=>'/command'),
            array('title'=>"Link text2", 'callback_data'=>'/command'),
            array('title'=>'Link text3', 'callback_data'=>'/command'),
            array('title'=>'Link text4', 'callback_data'=>'/command'),
            array('title'=>'Link text5', 'callback_data'=>'/command')
      );

$i=0;
$r=1;
foreach ($stmt as $row)
{
    // here's the trick: $options[$r][]
    $options[$r][] = array('text'=>urlencode($row['title']), 'callback_data'=>'/x');
    $i++;
    if($i===2) { // if counter at row 3
        $r++; // increase row index here
        $i=0; // reset counter
    };
}

// for debugging only:
echo "<pre>";
var_dump($options);
echo "</pre>";
                                        // note the change here
$keyb           = array('inline_keyboard' => $options);
?>

@abfackeln 的版本(如果你懂德语,那该是个什么样的用户名...)实际上更好,因为他使用模数并且不重置计数器。

在这里见谅,我必须跳进去喊:

不!

其他答案。

PHP 已经提供了一个可以将数组分解为 "chunks" 的函数,称为 array_chunk()。不要使用递增和模数条件来生成密钥,使用这个函数。

代码(Demo):

$stmt = array(
            array('title'=>'Link ? text1', 'callback_data'=>'/x'),
            array('title'=>"Link & text2", 'callback_data'=>'/x'),
            array('title'=>'Link # text3', 'callback_data'=>'/x'),
            array('title'=>'Link * text4', 'callback_data'=>'/x'),
            array('title'=>'Link @ text5', 'callback_data'=>'/x')
      );

// prepare the subarrays using resultset
foreach($stmt as $row){
    $options[]=['text'=>urlencode($row['title']),'callback_data'=>'/x'];
}

// then chunk into pairs, assign key, json encode --> DONE
var_export(json_encode(['inline_keyboard'=>array_chunk($options,2)]));
//sendMessage($chatID,$reply,json_encode(['inline_keyboard'=>array_chunk($options,2)]));

输出:

{"inline_keyboard":[[[{"text":"Link+%3F+text1","callback_data":"\/x"},{"text":"Link+%26+text2","callback_data":"\/x"}],[{"text":"Link+%23+text3","callback_data":"\/x"},{"text":"Link+%2A+text4","callback_data":"\/x"}],[{"text":"Link+%40+text5","callback_data":"\/x"}]]]}