在 Laravel 中,在 session 中传递不同类型的 flash 消息的最佳方式

Posted

技术标签:

【中文标题】在 Laravel 中,在 session 中传递不同类型的 flash 消息的最佳方式【英文标题】:In Laravel, the best way to pass different types of flash messages in the session 【发布时间】:2014-01-27 01:33:09 【问题描述】:

我正在 Laravel 中制作我的第一个应用程序,并试图让我的头脑了解会话闪存消息。据我所知,在我的控制器操作中,我可以通过设置来设置一条闪光消息

Redirect::to('users/login')->with('message', 'Thanks for registering!'); //is this actually OK?

对于重定向到另一个路由的情况,或者

Session::flash('message', 'This is a message!'); 

在我的主刀片模板中,我将拥有:

@if(Session::has('message'))
<p class="alert alert-info"> Session::get('message') </p>
@endif

您可能已经注意到,我在我的应用程序中使用了 Bootstrap 3,并希望使用不同的消息类:alert-infoalert-warningalert-danger 等。

假设在我的控制器中我知道我正在设置什么类型的消息,那么在视图中传递和显示它的最佳方式是什么?我应该在会话中为每种类型设置单独的消息(例如Session::flash('message_danger', 'This is a nasty message! Something's wrong.');)吗?然后我需要为刀片模板中的每条消息使用单独的 if 语句。

任何建议表示赞赏。

【问题讨论】:

itsolutionstuff.com/post/… 对我有帮助。 【参考方案1】:

一种解决方案是将两个变量闪存到会话中:

    消息本身 警报的“类别”

例如:

Session::flash('message', 'This is a message!'); 
Session::flash('alert-class', 'alert-danger'); 

那么在你看来:

@if(Session::has('message'))
<p class="alert  Session::get('alert-class', 'alert-info') "> Session::get('message') </p>
@endif

请注意,我已将 default value 放入 Session::get()。这样,您只需要在警告不是 alert-info 类的情况下覆盖它。

(这是一个简单的例子,未经测试:))

【讨论】:

有趣,我不知道Session::get() 的默认参数,它会派上用场。 像大多数 Flash 消息解决方案一样,这只处理一条消息。很多时候,有必要能够触发一堆消息,每条消息都可能具有不同的严重性,并将它们全部显示出来。 这是我们在项目中使用的gist.github.com/YavorK/7aa6e839dbe93e8854e4b033e31836a4 这太适得其反了......为什么每个人都赞成这个? @Goowik - 说它适得其反而不提供更高效的解决方案是适得其反的。【参考方案2】:

另一种解决方案是创建一个辅助类 How to Create helper classes here

class Helper
     public static function format_message($message,$type)
    
         return '<p class="alert alert-'.$type.'">'.$message.'</p>'
    

那么你就可以这样做了。

Redirect::to('users/login')->with('message', Helper::format_message('A bla blah occured','error'));

Redirect::to('users/login')->with('message', Helper::format_message('Thanks for registering!','info'));

在你看来

@if(Session::has('message'))
    Session::get('message')
@endif

【讨论】:

我不知道我是否会推荐这种方法,因为它会将 html 从视图中取出并放入代码中。【参考方案3】:

我的方法是总是 Redirect::back() 或 Redirect::to():

Redirect::back()->with('message', 'error|There was an error...');

Redirect::back()->with('message', 'message|Record updated.');

Redirect::to('/')->with('message', 'success|Record updated.');

我有一个辅助函数让它为我工作,通常这是在一个单独的服务中:

use Illuminate\Support\Facades\Session;

function displayAlert()

      if (Session::has('message'))
      
         list($type, $message) = explode('|', Session::get('message'));

         $type = $type == 'error' ?: 'danger';
         $type = $type == 'message' ?: 'info';

         return sprintf('<div class="alert alert-%s">%s</div>', $type, $message);
      

      return '';

在我的视图或布局中,我只是这样做

 displayAlert() 

【讨论】:

这简直太棒了,但这是如何工作的$type = $type == 'error' : 'danger'; 你把你的助手放在一个单独的助手类中的什么地方?【参考方案4】:

在你看来:

<div class="flash-message">
  @foreach (['danger', 'warning', 'success', 'info'] as $msg)
    @if(Session::has('alert-' . $msg))
    <p class="alert alert- $msg "> Session::get('alert-' . $msg) </p>
    @endif
  @endforeach
</div>

然后在控制器中设置一个闪烁消息:

Session::flash('alert-danger', 'danger');
Session::flash('alert-warning', 'warning');
Session::flash('alert-success', 'success');
Session::flash('alert-info', 'info');

【讨论】:

【参考方案5】:

你可以使用 Laravel 宏。

您可以在app/helpers 中创建macros.php 并将其包含在routes.php 中。

如果您希望将宏放在类文件中,可以查看本教程:http://chrishayes.ca/blog/code/laravel-4-object-oriented-form-html-macros-classes-service-provider

HTML::macro('alert', function($class='alert-danger', $value="",$show=false)


    $display = $show ? 'display:block' : 'display:none';

    return
        '<div class="alert '.$class.'" style="'.$display.'">
            <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
            <strong><i class="fa fa-times"></i></strong>'.$value.'
        </div>';
);

在您的控制器中:

Session::flash('message', 'This is so dangerous!'); 
Session::flash('alert', 'alert-danger');

在你看来

@if(Session::has('message') && Session::has('alert') )
  HTML::alert($class=Session::get('alert'), $value=Session::get('message'), $show=true)
@endif

【讨论】:

【参考方案6】:

只需返回您想要处理的“标志”,而无需使用任何额外的用户函数。 控制器:

return \Redirect::back()->withSuccess( 'Message you want show in View' );

请注意,我使用了“成功”标志。

观点:

@if( Session::has( 'success' ))
      Session::get( 'success' ) 
@elseif( Session::has( 'warning' ))
      Session::get( 'warning' )  <!-- here to 'withWarning()' -->
@endif

是的,它确实有效!

【讨论】:

您的回答中有大量错别字,但您的方法效果很好。【参考方案7】:

对于我的应用程序,我做了一个辅助函数:

function message( $message , $status = 'success', $redirectPath = null )

     $redirectPath = $redirectPath == null ? back() : redirect( $redirectPath );

     return $redirectPath->with([
         'message'   =>  $message,
         'status'    =>  $status,
    ]);

消息布局,main.layouts.message:

@if($status)
   <div class="center-block affix alert alert-$status">
     <i class="fa fa- $status == 'success' ? 'check' : $status"></i>
     <span>
         $message 
     </span>
   </div>
@endif

并导入每个显示消息的位置:

@include('main.layouts.message', [
    'status'    =>  session('status'),
    'message'   =>  session('message'),
])

【讨论】:

【参考方案8】:

我通常这样做

在我的 store() 函数中,一旦正确保存,我就会发出成功警报。

\Session::flash('flash_message','Office successfully updated.');

在我的 destroy() 函数中,我想将警报设置为红色,以便通知它已删除

\Session::flash('flash_message_delete','Office successfully deleted.');

注意,我们创建了两个具有不同 Flash 名称的警报。

在我看来,我会在适当的时间调用特定警报时添加条件

@if(Session::has('flash_message'))
    <div class="alert alert-success"><span class="glyphicon glyphicon-ok"></span><em> !! session('flash_message') !!</em></div>
@endif
@if(Session::has('flash_message_delete'))
    <div class="alert alert-danger"><span class="glyphicon glyphicon-ok"></span><em> !! session('flash_message_delete') !!</em></div>
@endif

在这里你可以找到不同的flash消息样式Flash Messages in Laravel 5

【讨论】:

【参考方案9】:

您可以制作多条消息并使用不同的类型。 请按照以下步骤操作:

    创建文件:“app/Components/FlashMessages.php
namespace App\Components;

trait FlashMessages

  protected static function message($level = 'info', $message = null)
  
      if (session()->has('messages')) 
          $messages = session()->pull('messages');
      

      $messages[] = $message = ['level' => $level, 'message' => $message];

      session()->flash('messages', $messages);

      return $message;
  

  protected static function messages()
  
      return self::hasMessages() ? session()->pull('messages') : [];
  

  protected static function hasMessages()
  
      return session()->has('messages');
  

  protected static function success($message)
  
      return self::message('success', $message);
  

  protected static function info($message)
  
      return self::message('info', $message);
  

  protected static function warning($message)
  
      return self::message('warning', $message);
  

  protected static function danger($message)
  
      return self::message('danger', $message);
  

    在您的基本控制器“app/Http/Controllers/Controller.php”上。
namespace App\Http\Controllers;

use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesResources;

use App\Components\FlashMessages;

class Controller extends BaseController

    use AuthorizesRequests, AuthorizesResources, DispatchesJobs, ValidatesRequests;

    use FlashMessages;

这将使FlashMessages trait 可用于所有扩展此类的控制器。

    为我们的消息创建刀片模板:“views/partials/messages.blade.php
@if (count($messages))
<div class="row">
  <div class="col-md-12">
  @foreach ($messages as $message)
      <div class="alert alert- $message['level'] ">!! $message['message'] !!</div>
  @endforeach
  </div>
</div>
@endif
    关于“app/Providers/AppServiceProvider.php”的“boot()”方法:
namespace App\Providers;

use Illuminate\Support\ServiceProvider; 

use App\Components\FlashMessages;

class AppServiceProvider extends ServiceProvider

  use FlashMessages;

    public function boot()
    
        view()->composer('partials.messages', function ($view) 

          $messages = self::messages();

          return $view->with('messages', $messages);
      );
    

    ...

这将使$messages 变量在“views/partials/message.blade.php”模板被调用时可用。

    在您的模板中,包含我们的消息模板 - “views/partials/messages.blade.php
<div class="row">
  <p>Page title goes here</p>
</div>

@include ('partials.messages')

<div class="row">
  <div class="col-md-12">
      Page content goes here
  </div>
</div>

您只需要将消息模板包含在您想要在页面上显示消息的任何位置。

    在您的控制器上,您可以简单地执行以下操作来推送 Flash 消息:
use App\Components\FlashMessages;

class ProductsController 

  use FlashMessages;

  public function store(Request $request)
  
      self::message('info', 'Just a plain message.');
      self::message('success', 'Item has been added.');
      self::message('warning', 'Service is currently under maintenance.');
      self::message('danger', 'An unknown error occured.');

      //or

      self::info('Just a plain message.');
      self::success('Item has been added.');
      self::warning('Service is currently under maintenance.');
      self::danger('An unknown error occured.');
  

  ...

希望对你有帮助。

【讨论】:

不错。实际需要在 Laravel 中找到多条消息的解决方案。【参考方案10】:

不太喜欢所提供的解决方案(即:多个变量、辅助类、循环通过“可能存在的变量”)。下面是一个解决方案,它使用数组而不是两个单独的变量。如果您愿意,它也可以轻松扩展以处理多个错误,但为简单起见,我将其保留为一条消息:

使用 Flash 消息重定向数组

    return redirect('/admin/permissions')->with('flash_message', ['success','Updated Successfully','Permission "'. $permission->name .'" updated successfully!']);

基于数组内容的输出:

@if(Session::has('flash_message'))
    <script type="text/javascript">
        jQuery(document).ready(function()
            bootstrapNotify('session('flash_message')[0]','session('flash_message')[1]','session('flash_message')[2]');
        );
    </script>
@endif

不相关,因为您可能有自己的通知方法/插件 - 但只是为了清楚起见 - bootstrapNotify 只是从 http://bootstrap-notify.remabledesigns.com/ 启动引导通知:

function bootstrapNotify(type,title = 'Notification',message) 
    switch (type) 
        case 'success':
            icon = "la-check-circle";
            break;
        case 'danger':
            icon = "la-times-circle";
            break;
        case 'warning':
            icon = "la-exclamation-circle";
    

    $.notify(message: message, title : title, icon : "icon la "+ icon, type: type,allow_dismiss: true,newest_on_top: false,mouse_over: true,showProgressbar: false,spacing: 10,timer: 4000,placement: from: "top",align: "right",offset: x: 30,y: 30,delay: 1000,z_index: 10000,animate: enter: "animated bounce",exit: "animated fadeOut");

【讨论】:

【参考方案11】:

我认为以下代码适用于较少的代码行。

        session()->flash('toast', [
        'status' => 'success', 
        'body' => 'Body',
        'topic' => 'Success']
    );

我使用的是烤面包机包,但您可以在视图中看到类似的东西。

             toastr.session('toast.status')(
              'session('toast.body')', 
              'session('toast.topic')'
             );

【讨论】:

【参考方案12】:

在控制器中:

Redirect::to('/path')->with('message', 'your message'); 

或者

Session::flash('message', 'your message'); 

在 Blade 中显示消息中的 Blade As ur Desired Pattern:

@if(Session::has('message'))
    <div class="alert alert-className">
        session('message')
    </div>
@endif

【讨论】:

你如何传递类名?【参考方案13】:

只需在会话中发送一个数组而不是一个字符串,如下所示:

Session::flash('message', ['text'=>'this is a danger message','type'=>'danger']);

@if(Session::has('message'))
    <div class="alert alert-session('message')['type']">
        session('message')['text']
    </div>
@endif

【讨论】:

【参考方案14】:

我遇到了这种发送消息的优雅方式。它是由 Laracast 的 Jeffrey Way 制作的。 看看这个... https://github.com/laracasts/flash

【讨论】:

【参考方案15】:

如果您想使用 Bootstrap Alert 使您的视图更具交互性。你可以这样做:

在你的函数中:-

if($author->save())
    Session::flash('message', 'Author has been successfully added');
    Session::flash('class', 'success'); //you can replace success by [info,warning,danger]
    return redirect('main/successlogin');

在你看来:-

@if(Session::has('message'))
    <div class="alert alert-Session::get('class') alert-dismissible fade show w-50 ml-auto alert-custom"
        role="alert">
         Session::get('message') 
        <button type="button" class="close" data-dismiss="alert" aria-label="Close">
            <span aria-hidden="true">&times;</span>
        </button>
    </div>
@endif

【讨论】:

【参考方案16】:

我喜欢最受好评的答案。 就我而言,我决定使用 session() 函数包装器,以避免在刀片模板中调用 facade。在控制器中也是如此。在我看来,它使代码更整洁。

线

Session::flash('message', 'This is a message!');

变成

session()-&gt;flash('message', 'This is a message!');

在刀片模板中

session()-&gt;get('alert-class', 'alert-info');

干杯!

【讨论】:

以上是关于在 Laravel 中,在 session 中传递不同类型的 flash 消息的最佳方式的主要内容,如果未能解决你的问题,请参考以下文章

laravel框架中的session问题

laravel session redis 设置

在控制器中设置Laravel会话生存期

从 Laravel Session 数组中删除项目

laravel5.6框架中session的使用

我应该在 Laravel 5.7 中更好地使用 session() 或 collect() 辅助函数吗?