Laravel框架实现多个视图共享相同数据的方法详解


Posted in PHP onJuly 09, 2019

本文实例讲述了Laravel框架实现多个视图共享相同数据的方法。分享给大家供大家参考,具体如下:

最近在用Laravel写一个cms,还没有完成,但是也遇到了许多难点,比如cms后台每个视图都要展示相同的导航菜单数据。

环境:

PHP 7.1
Apache 2.4
MySQL 5.7
Laravel 5.4

  • 传统方法

假设使用传统的方法,应该是在每个控制器中都调用数据,然后把数据都塞给视图。

    $menu = DB::table('menu')->get();
    return view('xx',['menu'=>$menu]);
  • 稍微优化
  • 新建一个BaseController,然后让BaseController去获取数据,然后在每个控制器都继承BaseController,最后将数据塞到视图中。

    基类

    class BaseController{
      protected $menu = null;//菜单数据
      public function __construct(){
        $this->getMenu();//获取导航菜单
      }
      public function getMenu(){
        $this->menu = DB::table('menu')->get();
      }
    }

    A控制器

    class AController extends BaseController{
      public function index(){
        return view('admin.index',['menu'=>$this->menu,'user'=>$user]);
      }
    }

    缺点:在每个控制器中都需要重新设置相同的模板的数据(menu)

    • 最好优化方案

    使用Laravel中的View Composers来解决这个问题

    1、在App\Providers下创建一个ComposerServiceProvider类

    <?php
    namespace App\Providers;
    use Illuminate\Support\Facades\View;
    use Illuminate\Support\ServiceProvider;
    class ComposerServiceProvider extends ServiceProvider {
      /**
       * Register bindings in the container.
       *
       * @return void
       */
      public function boot() {
        // 基于类的view composer
        View::composer(
          'admin.common.*', 'App\Http\ViewComposers\AdminComposer'
        );
      }
      /**
       * Register the service provider.
       *
       * @return void
       */
      public function register() {
        //
      }
    }

    在boot方法中定义要监听的视图,还可以使用通配符,这里我写的是admin.common.*,如果admin.common.* 下的视图被渲染的话将会调用App\Http\ViewComposers\AdminComposer@composer 方法

    2、注册ComposerServiceProvider

    config/app.php文件下的providers数组中进行注册

    App\Providers\ComposerServiceProvider::class,

    3、创建AdminComposer类

    Laravel推荐把view composer类放在app\Http\ViewComposers目录下,这个目录一开始是没有的,需要新建

    <?php
    namespace App\Http\ViewComposers;
    use App\Libs\CommonUtils;
    use Illuminate\Http\Request;
    use Illuminate\View\View;
    class AdminComposer {
      private $data = null;//CommonUtils对象
      public function __construct(Request $request) {
        $this->data = new CommonUtils($request);//新建一个CommonUtils对象
      }
      public function compose(View $view) {
        $view->with([
          'admin' => $this->data->admin,
          'mbx' => $this->data->mbx,
          'menu' => $this->data->menu,
          'msg' => $this->data->msg
        ]);//填充数据
      }
    }

    在这里我在构造方法中创建了一个对象,这个对象中包含着数据

    5、CommonUtils文件

    <?php
    /**
     * Created by PhpStorm.
     * User: Administrator
     * Date: 2017/4/20 0020
     * Time: 19:49
     */
    namespace App\Libs;
    use App\Admin;
    use App\Perm;
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\DB;
    class CommonUtils {
      public $admin = null;//管理员对象
      public $menu = null;//菜单对象
      public $mbx = null;//面包屑对象
      public $msg = null;//消息对象
      /**
       * 构造函数
       */
      public function __construct(Request $request) {
        $this->init($request);
      }
      /**
       * 初始化函数
       */
      private function init(Request $request) {
        $this->getAdmin($request);
        $this->getMsg();
        $this->getMenu($request);
        $this->getMbx($request);
      }
      /**
       * 获取管理员数据
       */
      private function getAdmin() {
        $this->admin = session('admin');
      }
      /**
       * 获取后台菜单数据
       */
      private function getMenu(Request $request) {
        $menu = DB::table('menu')->where('parentid', 0)->orderBy('sort')->get();
        $router = $request->getPathInfo();
        $perm = new Perm();
        $mbx = $perm->getMbx($router);
        foreach ($menu as $k => $m) {
          $m->active = '';
          //读取子菜单
          $childMenu = DB::table('menu')->where('parentid', $m->id)->orderBy('sort')->get();
          if (count($childMenu) > 0) {
            foreach($childMenu as $v){
              $v->active = '';
              if($mbx[0]->router == $v->router){
                $v->active = 'active';
                $m->active = 'active';
              }
            }
            $m->childMenu = $childMenu;
          } else {
            $m->childMenu = null;
          }
        }
        $this->menu = $menu;
      }
      /**
       * 获取面包屑
       */
      private function getMbx(Request $request) {
        $router = $request->getPathInfo();
        $perm = new Perm();
        $mbx = $perm->getMbx($router);
        $this->mbx = $mbx;
      }
      /**
       * 获取未读消息
       */
      private function getMsg() {
        $adminModel = new Admin();
        $toId = $this->admin->id;
        $this->msg = $adminModel->getUnReadMsg($toId);
      }
    }

    在这里面分别获取了管理员、菜单、面包屑、消息数据,这些数据都是每个后台页面都要使用到的。

    注意:这里我将类定义成了CommonUtils,感觉名字取得不好,CommonUtils是存放在App\Libs下的,这个Libs文件夹是我新建的,用于存放工具类的。如果需要给App\Libs文件夹添加自动加载,需要在composer.json文件里做如下修改。

    Laravel框架实现多个视图共享相同数据的方法详解

    希望本文所述对大家基于Laravel框架的PHP程序设计有所帮助。

    PHP 相关文章推荐
    php购物车实现代码
    Oct 10 PHP
    PHP重定向的3种方式
    Mar 07 PHP
    codeigniter框架The URI you submitted has disallowed characters错误解决方法
    May 06 PHP
    基于OpenCart 开发支付宝,财付通,微信支付参数错误问题
    Oct 01 PHP
    WordPress中用于检索模版的相关PHP函数使用解析
    Dec 15 PHP
    Yii2搭建后台并实现rbac权限控制完整实例教程
    Apr 28 PHP
    php file_get_contents取文件中数组元素的方法
    Apr 01 PHP
    php实现与python进行socket通信的方法示例
    Aug 30 PHP
    ThinkPHP框架中使用Memcached缓存数据的方法
    Mar 31 PHP
    实现PHP中session存储及删除变量
    Oct 15 PHP
    关于Yii2框架跑脚本时内存泄漏问题的分析与解决
    Dec 01 PHP
    Laravel框架处理用户的请求操作详解
    Dec 20 PHP
    Laravel5.1框架注册中间件的三种场景详解
    Jul 09 #PHP
    PHP使用 Pear 进行安装和卸载包的方法详解
    Jul 08 #PHP
    PHP 7.4中使用预加载的方法详解
    Jul 08 #PHP
    php apache开启跨域模式过程详解
    Jul 08 #PHP
    php如何把表单内容提交到数据库
    Jul 08 #PHP
    php利用array_search与array_column实现二维数组查找
    Jul 08 #PHP
    php实现获取近几日、月时间示例
    Jul 06 #PHP
    You might like
    PHP的单引号和双引号 字符串效率
    2009/05/27 PHP
    PHP file_get_contents 函数超时的几种解决方法
    2009/07/30 PHP
    php5.4以上版本GBK编码下htmlspecialchars输出为空问题解决方法汇总
    2015/04/03 PHP
    php使用lua+redis实现限流,计数器模式,令牌桶模式
    2019/04/04 PHP
    Laravel框架实现的上传图片到七牛功能详解
    2019/09/06 PHP
    JS实多级联动下拉菜单类,简单实现省市区联动菜单!
    2007/05/03 Javascript
    浅说js变量
    2011/05/25 Javascript
    js/ajax跨越访问-jsonp的原理和实例(javascript和jquery实现代码)
    2012/12/27 Javascript
    Jquery的each里用return true或false代替break或continue
    2014/05/21 Javascript
    jQuery实现拖动调整表格单元格大小的代码实例
    2015/01/13 Javascript
    js 获取元素在页面上的偏移量的方法汇总
    2015/04/13 Javascript
    JS基于MSClass和setInterval实现ajax定时采集信息并滚动显示的方法
    2016/04/18 Javascript
    js设置和获取自定义属性的方法
    2016/10/20 Javascript
    js提示框替代系统alert,自动关闭alert对话框的实现方法
    2016/11/07 Javascript
    jQuery实现的仿百度,仿谷歌搜索下拉框效果示例
    2016/12/30 Javascript
    vue使用stompjs实现mqtt消息推送通知
    2017/06/22 Javascript
    基于JSON数据格式详解
    2017/08/31 Javascript
    thinkjs微信中控之微信鉴权登陆的实现代码
    2019/08/08 Javascript
    layui上传图片到服务器的非项目目录下的方法
    2019/09/26 Javascript
    基于Vue sessionStorage实现保留搜索框搜索内容
    2020/06/01 Javascript
    [01:21]DOTA2新纪元-7.0新版本即将开启!
    2016/12/11 DOTA
    使用PDB简单调试Python程序简明指南
    2015/04/25 Python
    Python中对象迭代与反迭代的技巧总结
    2016/09/17 Python
    python中Pycharm 输出中文或打印中文乱码现象的解决办法
    2017/06/16 Python
    Python I/O与进程的详细讲解
    2019/03/08 Python
    详解pandas删除缺失数据(pd.dropna()方法)
    2019/06/25 Python
    Python 面向对象部分知识点小结
    2020/03/09 Python
    找Python安装目录,设置环境路径以及在命令行运行python脚本实例
    2020/03/09 Python
    在主流系统之上安装Pygame的方法
    2020/05/20 Python
    python获取天气接口给指定微信好友发天气预报
    2020/12/28 Python
    Python实现京东抢秒杀功能
    2021/01/25 Python
    html5 跨文档消息传输示例探讨
    2013/04/01 HTML / CSS
    2014年重阳节老干部座谈会上的讲话稿
    2014/09/25 职场文书
    布达拉宫导游词
    2015/02/02 职场文书
    你知道Java Spring的两种事务吗
    2022/03/16 Java/Android
    Python实现双向链表基本操作
    2022/05/25 Python