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 09 PHP
    由php if 想到的些问题
    Mar 22 PHP
    php 文章采集正则代码
    Dec 28 PHP
    如何在php中正确的使用json
    Aug 06 PHP
    ThinkPHP实现跨模块调用操作方法概述
    Jun 20 PHP
    PHP错误Parse error: syntax error, unexpected end of file in test.php on line 12解决方法
    Jun 23 PHP
    php递归json类实例
    Dec 02 PHP
    Linux中为php配置伪静态
    Dec 17 PHP
    php实现httpRequest的方法
    Mar 13 PHP
    以实例全面讲解PHP中多进程编程的相关函数的使用
    Aug 18 PHP
    详谈symfony window下的安装 安装时候出现的问题以及解决方法
    Sep 28 PHP
    PHP数组式访问接口ArrayAccess用法分析
    Dec 28 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
    解析centos中Apache、php、mysql 默认安装路径
    2013/06/25 PHP
    PHP数组相关函数汇总
    2015/03/24 PHP
    PHP开发Apache服务器配置
    2015/07/15 PHP
    PHP函数超时处理方法
    2016/02/14 PHP
    php使用ftp实现文件上传与下载功能
    2017/07/21 PHP
    使用YII2框架实现微信公众号中表单提交功能
    2017/09/04 PHP
    javascript 快速排序函数代码
    2012/05/30 Javascript
    JS区分浏览器页面是刷新还是关闭
    2016/04/17 Javascript
    jQuery+php实时获取及响应文本框输入内容的方法
    2016/05/24 Javascript
    如何使用jquery实现文字上下滚动效果
    2016/10/12 Javascript
    微信小程序Redux绑定实例详解
    2017/06/07 Javascript
    Django+Vue跨域环境配置详解
    2018/07/06 Javascript
    微信小程序将字符串生成二维码图片的操作方法
    2018/07/17 Javascript
    一步一步的了解webpack4的splitChunk插件(小结)
    2018/09/17 Javascript
    js删除对象/数组中null、undefined、空对象及空数组方法示例
    2018/11/14 Javascript
    微信小程序实现炫酷的弹出式菜单特效
    2019/01/28 Javascript
    layui实现数据表格自定义数据项
    2019/10/26 Javascript
    JavaScript对象字面量和构造函数原理与用法详解
    2020/04/18 Javascript
    JavaScript图像放大镜效果实现方法详解
    2020/06/28 Javascript
    Scrapy的简单使用教程
    2017/10/24 Python
    python爬取微信公众号文章
    2018/08/31 Python
    详解Canvas 跨域脱坑实践
    2018/11/07 HTML / CSS
    科沃斯机器人官网商城:Ecovacs
    2016/08/29 全球购物
    ONLY德国官方在线商店:购买时尚女装
    2017/09/21 全球购物
    英国山地公路自行车商店:Tweeks Cycles
    2018/03/16 全球购物
    EntityManager都有哪些方法
    2013/11/01 面试题
    开业庆典答谢词
    2014/01/18 职场文书
    社区党员先进事迹
    2014/01/22 职场文书
    临床专业自荐信
    2014/06/22 职场文书
    医学生求职信
    2014/07/01 职场文书
    给病人的慰问信
    2015/03/23 职场文书
    vue首次渲染全过程
    2021/04/21 Vue.js
    mysql创建存储过程及函数详解
    2021/12/04 MySQL
    Spring Data JPA框架的核心概念和Repository接口
    2022/04/28 Java/Android
    介绍一下28个JS常用数组方法
    2022/05/06 Javascript
    shell进度条追踪指令执行时间的场景分析
    2022/06/16 Servers