【问题标题】:Implementing a flash message on a Smarty site?在 Smarty 网站上实施 Flash 消息?
【发布时间】:2011-03-23 13:44:17
【问题描述】:

我正在尝试在一个代码非常混乱的 PHP 站点中实现一个“Flash 消息”(一条小消息,将显示在“下一个”请求的顶部,说诸如“记录已保存”之类的内容)并使用 Smarty。

我能想到的最好的方法是:

  1. 我将消息设置在 $_SESSION 中一个特别命名的变量中
  2. 我的“标题”模板检查该变量 ($smarty.session.flash),如果已设置,它会显示消息
  3. 渲染后,并且仅在渲染模板时,清除 $_SESSION 变量。

我的问题是#3。我能找到的唯一方法是向 Smarty 注册一个输出过滤器:

function smarty_outputfilter_flashmessage($tpl_output, $smarty) {
    if (isset($_SESSION['flash'])) {
        $_SESSION['flash'] = "";
    }
    return $tpl_output;
}

$smarty->register_outputfilter("smarty_outputfilter_flashmessage");

问题在于,如果一个模板有子模板,那么每个子模板都会调用该函数。另外,代码中有很多地方可以这样做

$variable = $smarty->fetch('something.tpl')

这也会触发我的输出过滤器。

发生这种情况时,输出过滤器会在标题模板呈现之前清除会话变量,并且消息会丢失。

关于如何更好地做到这一点的任何想法/建议?

当请求“结束”时,是否有某种 PHP 内置回调来执行自定义函数? (这样,我可以在那里添加清除,并让 output_filter 简单地设置一个变量来显示 something 是否被渲染)

理想情况下,除非代码调用 die(),否则会被调用?

或者,当然,另一种完全不同的更好的方法来做到这一点?

谢谢!
丹尼尔

【问题讨论】:

    标签: php session smarty flash-message


    【解决方案1】:

    我已经很久没有认真使用 PHP 或 Smarty 了,但与其尝试猜测模板何时呈现,你不能做一个 Smarty 函数来执行以下操作:

    function smarty_function_pop_flash_message($params, $smarty) {
        $msg = "";
        if (isset($_SESSION['flash'])) {
            $msg = $_SESSION['flash'];
            $_SESSION['flash'] = "";
        }
        return $msg;
    }
    

    然后在显示此消息的模板中:

    {if isset($smarty.session.flash) && $smarty.session.flash != ''}
        <div id="flash">{pop_flash_message}</div>
    {/if}
    

    【讨论】:

      【解决方案2】:

      我以前用过Smarty的时候,想要能显示消息,我就用了下面的方法。

      在处理动作然后生成消息的 PHP 脚本中:

      $_SESSION['message'][] = 'The Message Content!';
      

      在处理下一个请求/页面并调用 Smarty 模板的 PHP 脚本中:

      $smarty->assign( 'messages' , $_SESSION['message'] );
      unset( $_SESSION['messages'] );
      

      在 Smarty 模板中(通常是一个经常重复使用的模板,如 Header 部分

      {include file='messages.tpl'}
      

      然后在“messages.tpl”Smarty 模板内

      {if $messages}
        <div id="messages">
          <ul>
            {foreach $messages as $m}
              <li>{$m}</li>
            {/foreach}
          </ul>
        </div>
      {/if}
      

      这并不完美,如果同时加载多个页面,消息可能会出现在错误的页面中(一种罕见的情况,但有可能),但过去对我来说效果很好。

      (注意:这些是拼凑的代码示例,请自行承担风险。)

      【讨论】:

      • 感谢您的回答。我看到的问题是,如果“下一个”请求以重定向而不是呈现模板结束,则消息会丢失,并且这发生在站点的几个地方。这就是为什么我在渲染时尝试清除 SESSION 变量,而不是在请求开始时清除
      • 只有在设置了 Smarty 变量(并且未设置会话变量)执行header( 'Location: newpage.html' );die(); 之前,如果发生重定向,消息才会丢失.因此,尽可能将重定向处理到页面顶部,并且一旦通过了这些障碍,然后花时间为 Smarty 输出设置变量。
      猜你喜欢
      • 2012-06-16
      • 1970-01-01
      • 1970-01-01
      • 2010-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-24
      • 2013-02-02
      相关资源
      最近更新 更多