PHP Telegram按钮数组无法正常显示,请求排查错误原因
问题排查:Telegram按钮数组无法正常下发
我创建了一个Telegram按钮数组,用print_r输出的结构如下:
Array ( [0] => Array ( [0] => Array ( [text] => 1. Bayer Leverkusen - 1. FC Köln [callback_data] => 64136 ) ) [1] => Array ( [0] => Array ( [text] => 2. 1. FSV Mainz 05 - FC Schalke 04 [callback_data] => 64142 ) ) [2] => Array ( [0] => Array ( [text] => 3. FC Augsburg - 1. FC Union Berlin [callback_data] => 64135 ) ) [3] => Array ( [0] => Array ( [text] => 4. Borussia Mönchengladbach - VfL Bochum [callback_data] => 64138 ) ) [4] => Array ( [0] => Array ( [text] => 5. SC Freiburg - RB Leipzig â [callback_data] => 64139 ) ) [5] => Array ( [0] => Array ( [text] => 6. Hertha BSC - VfB Stuttgart [callback_data] => 64140 ) ) [6] => Array ( [0] => Array ( [text] => 7. TSG 1899 Hoffenheim - Eintracht Frankfurt [callback_data] => 64141 ) ) [7] => Array ( [0] => Array ( [text] => 8. Werder Bremen - FC Bayern [callback_data] => 64143 ) ) [8] => Array ( [0] => Array ( [text] => 9. Borussia Dortmund - VfL Wolfsburg [callback_data] => 64137 ) ) [9] => Array ( ) )
生成该数组的PHP代码如下:
$table = 'prefix_tippspiel_teams'; $uid = 104; $green_checkmark = "\xE2\x9C\x85"; $min_date = ''; $max_date = ''; $counter = 0; $kb = array(); $lines = array(); $matchlist = array(); $abf_matches = db_query("SELECT sp.match_id, sp.datum, sp.heim_id, sp.gast_id, sp.tore_heim, sp.tore_gast, sp.finished, t1.team_id as heim_id, t1.team_name as heim_team, t1.team_icon as heim_icon, t2.team_id as gast_id, t2.team_name as gast_team, t2.team_icon as gast_icon FROM prefix_tippspiel_spiele as sp LEFT JOIN $table as t1 ON sp.heim_id = t1.team_id LEFT JOIN $table as t2 ON sp.gast_id = t2.team_id WHERE competition = 'liga' AND sp.spieltag = 31 ORDER BY sp.datum ASC"); while($row = db_fetch_assoc($abf_matches)) { if ($row['finished'] == 1) { continue; } if ($counter == 0 && $min_date == '') { $min_date = $row['datum']; } $max_date = $row['datum']; $data = http_build_query([ 'text' => utf8_encode("Wähle ein Spiel des ".$matchday.". Spieltages (" . date('d.m.y', $min_date) . " - " . date('d.m.y', $max_date) . ")"), 'chat_id' => $update['message']['from']['id'] ]); $mid = $row['match_id']; $tipp_done = ''; if (0 < db_result(db_query("SELECT COUNT(*) FROM prefix_tippspiel_tipps WHERE mid = " . $mid . " AND uid = " . $uid . " AND (tore_heim IS NOT NULL AND tore_gast IS NOT NULL)"))) { $tipp_done = " ".$green_checkmark; } $heim_team = $row['heim_team']; $gast_team = $row['gast_team']; # hier statt 60 die aus den settings tippsperre...tipplock_seconds if (($row['datum'] - $tipplock_seconds) > $now) { $counter++; // Create keyboard array_push($lines, array("text" => utf8_encode($counter.". ".$heim_team." - ".$gast_team).$tipp_done, "callback_data" => $mid)); $rows++; if ($rows == 1) { array_push($kb, $lines); $lines = array(); $rows = 0; } # Matchlist-Array für spätere Abfrage füllen $matchlist[] = $counter.". ".$heim_team." - ".$gast_team; } } array_push($kb, $lines); $keyboard = json_encode(array("keyboard" => $kb, "one_time_keyboard" => true, "resize_keyboard" => true)); echo '<pre>'; print_r($kb); echo '</pre>';
目前遇到的问题是按钮无法正常下发;将代码中第一个array_push里的$heim_team替换为$gast_team时,按钮至少能正常显示。我怀疑$heim_team变量存在问题,但print_r输出显示主队名称设置正确,恳请帮忙排查错误所在。
排查方向与解决方案
- 字符编码二次编码问题
从print_r输出可见主队名称存在乱码(如Köln),这是因为如果数据库中team_name字段本身已是UTF-8编码,调用utf8_encode()会导致二次编码,生成Telegram无法解析的无效字符,进而导致按钮下发失败。
- 修复:确认数据库
team_name字段编码为UTF-8后,移除utf8_encode(),直接使用原始字符串:array_push($lines, array("text" => $counter.". ".$heim_team." - ".$gast_team.$tipp_done, "callback_data" => $mid));
- 空按钮行干扰
print_r输出末尾的空数组[9] => Array ()是循环结束后强制添加空$lines导致的,Telegram键盘不允许空行,会引发渲染错误。
- 修复:添加空数组判断后再推入
$kb:if (!empty($lines)) { array_push($kb, $lines); }
- 回调数据类型规范
Telegram要求callback_data为字符串类型,当前直接传入数字类型的$mid可能存在潜在兼容问题。
- 修复:显式转换为字符串:
"callback_data" => (string)$mid
- 未定义变量
$matchday
代码中使用了$matchday但未定义,会导致消息文本错误,可能影响整体消息下发。
- 修复:添加
$matchday的赋值语句,例如:$matchday = 31; // 对应SQL中的spieltag=31
内容的提问来源于stack exchange,提问作者Outi77
相关产品推荐
相关产品推荐

