PHP Twig模板根据变量设置单元格背景色失效问题排查
井字棋获胜方格子背景色不生效问题修复
问题原因
- 模板语法混用错误:Twig 模板使用独立的渲染语法,不支持嵌入 PHP 原生的
<?= ?>短标签。你写的<?=endAction()?>会被 Twig 当成普通文本直接输出到 HTML 里,最终生成的样式属性是background-color: <?=endAction()?>;,浏览器无法识别这个无效颜色值,自然不会渲染对应背景色。 - 变量调用逻辑错误:你已经通过控制器的
render()方法把获胜颜色$winnerColor传递给模板了,不需要、也不能在模板里直接调用控制器的endAction()方法。控制器方法是请求入口,直接调用会返回完整的响应对象而非单个颜色字符串,本身逻辑就不成立。 - 边界场景缺省值缺失:平局状态下你给
$winnerColor赋的是空字符串,这时候样式里的背景色值为空,属于无效CSS属性,也会导致样式失效。
基础修复方案(全局生效获胜方对应颜色)
- 先给控制器里的平局场景补默认背景色,避免空值:
public function endAction() { $message = ''; $winnerColor = '#FFFFFF'; // 平局默认白色背景 $game = $this->get('app.model.game_other_grid')->getGame(); if(Game::STATE_TIE == $game->getState()) { $message = 'Game Over: tie! how boring!'; } else if($game->getWinner() == Board::O){ $message = 'Game Over: ' . $game->getWinner() . ' has won!'; $winnerColor = '#00FF00'; } else if($game->getWinner() == Board::X){ $message = 'Game Over: ' . $game->getWinner() . ' has won!'; $winnerColor = '#FF8000'; } return $this->render( 'AppBundle:Default:end-2.html.twig', array( 'message' => $message, 'winnerColor' => $winnerColor, 'grid_number_2' => $game->getBoard()->getGrid(), )); }
- 修正 Twig 模板里的变量输出方式,把错误的 PHP 标签替换成 Twig 原生的变量输出语法:
<div class="board"> <table border> {% if grid_number_2 %} {% for row in grid_number_2 %} <tr> {% for cell in row %} <td width="100px" height="100px" style="background-color: {{ winnerColor }};"> <center> {{ cell }} </center> </td> {% endfor %} </tr> {% endfor %} {% endif %} </table> </div>
进阶优化(仅高亮获胜连线格子)
如果要实现只有连成线的三个获胜格子显示对应颜色、其余格子保持默认色的效果,需要额外传递获胜格子的坐标到模板,渲染时逐个判断:
- 控制器调整,新增获胜坐标传递(假设你的 Board 类已经有
getWinningCoords()方法返回获胜格子的[行号,列号]数组,平局时返回空数组):
public function endAction() { $message = ''; $winnerColor = '#FFFFFF'; $winningCoords = []; // 存储获胜连线的格子坐标 $game = $this->get('app.model.game_other_grid')->getGame(); if(Game::STATE_TIE == $game->getState()) { $message = 'Game Over: tie! how boring!'; } else if($game->getWinner() == Board::O){ $message = 'Game Over: ' . $game->getWinner() . ' has won!'; $winnerColor = '#00FF00'; $winningCoords = $game->getBoard()->getWinningCoords(); } else if($game->getWinner() == Board::X){ $message = 'Game Over: ' . $game->getWinner() . ' has won!'; $winnerColor = '#FF8000'; $winningCoords = $game->getBoard()->getWinningCoords(); } return $this->render( 'AppBundle:Default:end-2.html.twig', array( 'message' => $message, 'winnerColor' => $winnerColor, 'winningCoords' => $winningCoords, 'grid_number_2' => $game->getBoard()->getGrid(), )); }
- 模板调整,循环时记录行列索引,匹配到获胜坐标才渲染获胜色:
<div class="board"> <table border> {% if grid_number_2 %} {% for rowIndex, row in grid_number_2 %} <tr> {% for colIndex, cell in row %} {% set bgColor = '#FFFFFF' %} {% for coord in winningCoords %} {% if coord[0] == rowIndex and coord[1] == colIndex %} {% set bgColor = winnerColor %} {% endif %} {% endfor %} <td width="100px" height="100px" style="background-color: {{ bgColor }};"> <center> {{ cell }} </center> </td> {% endfor %} </tr> {% endfor %} {% endif %} </table> </div>
内容的提问来源于stack exchange,提问作者Stav_Sananes
相关产品推荐
相关产品推荐

