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
    在线短消息收发的程序,不用数据库
    Oct 09 PHP
    解决PHP在DOS命令行下却无法链接MySQL的技术笔记
    Dec 29 PHP
    解析php二分法查找数组是否包含某一元素
    May 23 PHP
    PHP 通过Socket收发十六进制数据的实现代码
    Aug 16 PHP
    ThinkPHP框架任意代码执行漏洞的利用及其修复方法
    Jul 04 PHP
    Chrome Web App开发小结
    Sep 04 PHP
    yii2.0之GridView自定义按钮和链接用法
    Dec 15 PHP
    PHP中strcmp()和strcasecmp()函数字符串比较用法分析
    Jan 07 PHP
    Zend Framework生成验证码并实现验证码验证功能(附demo源码下载)
    Mar 22 PHP
    使用php实现从身份证中提取生日
    May 09 PHP
    PHP常用操作类之通信数据封装类的实现
    Jul 16 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调用微博接口实现微博登录的方法示例
    2018/09/22 PHP
    Laravel框架实现调用百度翻译API功能示例
    2019/05/30 PHP
    php反序列化长度变化尾部字符串逃逸(0CTF-2016-piapiapia)
    2020/02/15 PHP
    js实现兼容IE6与IE7的DIV高度
    2010/05/13 Javascript
    基于jquery+thickbox仿校内登录注册框
    2010/06/07 Javascript
    javascript判断机器是否联网的2种方法
    2013/08/09 Javascript
    JavaScript实现的图像模糊算法代码分享
    2014/04/22 Javascript
    JavaScript实现弹出子窗口并传值给父窗口
    2014/12/18 Javascript
    基于JavaScript实现瀑布流布局(二)
    2016/01/26 Javascript
    BooStrap对导航条的改造实践小结
    2016/09/21 Javascript
    禁用backspace网页回退功能的实现代码
    2016/11/15 Javascript
    JS轮播图中缓动函数的封装
    2020/11/25 Javascript
    详解angular用$sce服务来过滤HTML标签
    2017/04/11 Javascript
    jQuery实现按比例缩放图片的方法
    2017/04/29 jQuery
    nodejs批量下载图片的实现方法
    2017/05/19 NodeJs
    微信小程序的分类页面制作
    2017/06/27 Javascript
    浅谈JS获取元素的N种方法及其动静态讨论
    2017/08/25 Javascript
    bootstrap-table.js扩展分页工具栏(增加跳转到xx页)功能
    2017/12/28 Javascript
    python网络编程之文件下载实例分析
    2015/05/20 Python
    Python中元组,列表,字典的区别
    2017/05/21 Python
    Python正则表达式非贪婪、多行匹配功能示例
    2017/08/08 Python
    Python中的函数作用域
    2018/05/07 Python
    python单线程文件传输的实例(C/S)
    2019/02/13 Python
    春节到了 教你使用python来抢票回家
    2020/01/06 Python
    Django搭建项目实战与避坑细节详解
    2020/12/06 Python
    香港个人化生活购物网站:Ballyhoo Limited
    2016/09/10 全球购物
    加拿大花店:1800Flowers.ca
    2016/11/16 全球购物
    日语求职信范文
    2013/12/17 职场文书
    残疾人创业典型事迹
    2014/02/01 职场文书
    情侣吵架检讨书
    2014/02/05 职场文书
    职业生涯规划书结束语
    2014/04/15 职场文书
    认真学习保证书
    2015/02/26 职场文书
    党小组鉴定意见
    2015/06/02 职场文书
    孔繁森观后感
    2015/06/10 职场文书
    毕业生求职自荐信(2016最新版)
    2016/01/28 职场文书
    如何解决springcloud feign 首次调用100%失败的问题
    2021/06/23 Java/Android