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 相关文章推荐
    Win9x/ME下Apache+PHP安装配置
    Oct 09 PHP
    PHP学习 运算符与运算符优先级
    Jun 15 PHP
    PHPMailer安装方法及简单实例
    Nov 25 PHP
    php 静态化实现代码
    Mar 20 PHP
    深入解析yii权限分级式访问控制的实现(非RBAC法)
    Jun 13 PHP
    实例介绍PHP的Reflection反射机制
    Aug 05 PHP
    浅谈本地WAMP环境的搭建
    May 13 PHP
    使用phpexcel类实现excel导入mysql数据库功能(实例代码)
    May 12 PHP
    php技巧小结【推荐】
    Jan 19 PHP
    PHP计算近1年的所有月份
    Mar 13 PHP
    PHP 7安装调试工具Xdebug扩展的方法教程
    Jun 17 PHP
    Laravel框架生命周期与原理分析
    Jun 12 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
    网页游戏开发入门教程三(简单程序应用)
    2009/11/02 PHP
    PHP字符串的编码问题的详细介绍
    2013/04/27 PHP
    PHP结合Jquery和ajax实现瀑布流特效
    2016/01/07 PHP
    详谈php中 strtr 和 str_replace 的效率问题
    2017/05/14 PHP
    PHP实现求连续子数组最大和问题2种解决方法
    2017/12/26 PHP
    php nginx 实时输出的简单实现方法
    2018/01/21 PHP
    javascript globalStorage类代码
    2009/06/04 Javascript
    JavaScript中的small()方法使用详解
    2015/06/08 Javascript
    JavaScript中Date.toSource()方法的使用教程
    2015/06/12 Javascript
    js判断文件格式及大小的简单实例(必看)
    2016/10/11 Javascript
    React-Native之定时器Timer的实现代码
    2017/10/04 Javascript
    VueJs 搭建Axios接口请求工具
    2017/11/20 Javascript
    JavaScript实现的贝塞尔曲线算法简单示例
    2018/01/30 Javascript
    微信小程序图片轮播组件gallery slider使用方法详解
    2018/01/31 Javascript
    详解处理bootstrap4不支持远程静态框问题
    2018/07/20 Javascript
    Bootstrap-table自定义可编辑每页显示记录数
    2018/09/07 Javascript
    深入理解js A*寻路算法原理与具体实现过程
    2018/12/13 Javascript
    layer更改皮肤的实现方法
    2019/09/11 Javascript
    LayUI switch 开关监听 获取属性值、更改状态的方法
    2019/09/21 Javascript
    JS中准确判断变量类型的方法
    2020/06/01 Javascript
    vue+iview实现分页及查询功能
    2020/11/17 Vue.js
    使用Python微信库itchat获得好友和群组已撤回的消息
    2018/06/24 Python
    python实现顺序表的简单代码
    2018/09/28 Python
    用django-allauth实现第三方登录的示例代码
    2019/06/24 Python
    Django多数据库配置及逆向生成model教程
    2020/03/28 Python
    浅谈优化Django ORM中的性能问题
    2020/07/09 Python
    HTML5触摸事件实现移动端简易进度条的实现方法
    2018/05/04 HTML / CSS
    GUESS Factory加拿大:牛仔裤、服装及配饰
    2019/09/20 全球购物
    软件测试企业面试试卷
    2016/07/13 面试题
    中医临床专业自我鉴定范文
    2014/01/15 职场文书
    营销部内勤岗位职责
    2014/04/30 职场文书
    部门2015年度工作总结
    2015/04/29 职场文书
    一道JS算法面试题——冒泡、选择排序
    2021/04/21 Javascript
    如何在Python项目中引入日志
    2021/05/31 Python
    CSS基础详解
    2021/10/16 HTML / CSS
    为Centos安装指定版本的Docker
    2022/04/01 Servers