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中的日期处理方法集锦
    Jan 02 PHP
    php面向对象全攻略 (七) 继承性
    Sep 30 PHP
    注册页面之前先验证用户名是否存在的php代码
    Jul 14 PHP
    PHP重定向的3种方式
    Mar 07 PHP
    php中的ini配置原理详解
    Oct 14 PHP
    ThinkPHP基于PHPExcel导入Excel文件的方法
    Oct 15 PHP
    PHP之sprintf函数用法详解
    Nov 12 PHP
    PHP入门教程之使用Mysqli操作数据库的方法(连接,查询,事务回滚等)
    Sep 11 PHP
    php微信公众平台配置接口开发程序
    Sep 22 PHP
    TP3.2批量上传文件或图片 同名冲突问题的解决方法
    Aug 01 PHP
    laravel中短信发送验证码的实现方法
    Apr 25 PHP
    PHP连接及操作PostgreSQL数据库的方法详解
    Jan 30 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
    第十二节--类的自动加载
    2006/11/16 PHP
    PHP 命令行工具 shell_exec, exec, passthru, system详细使用介绍
    2011/09/11 PHP
    php获取文件名称和扩展名的方法
    2017/02/07 PHP
    统计jQuery中各字符串出现次数的工具
    2012/05/03 Javascript
    javascript作用域容易记错的两个地方分析
    2012/06/22 Javascript
    深入理解javascript动态插入技术
    2013/11/12 Javascript
    Javascript中的匿名函数与封装介绍
    2015/03/15 Javascript
    使用jQuery实现更改默认alert框体
    2015/04/13 Javascript
    $.extend 的一个小问题
    2015/06/18 Javascript
    JS实现点击上移下移LI行数据的方法
    2015/08/05 Javascript
    JS实现的最简Table选项卡效果
    2015/10/14 Javascript
    JavaScript模拟数组合并concat
    2016/03/06 Javascript
    nodejs+mongodb+vue前后台配置ueditor的示例代码
    2018/01/02 NodeJs
    jQuery实现简单全选框
    2020/09/13 jQuery
    python连接mysql数据库示例(做增删改操作)
    2013/12/31 Python
    python中的多重继承实例讲解
    2014/09/28 Python
    Python最基本的数据类型以及对元组的介绍
    2015/04/14 Python
    在Python的Django框架中创建语言文件
    2015/07/27 Python
    Python单链表简单实现代码
    2016/04/27 Python
    如何使用Python的Requests包实现模拟登陆
    2018/04/27 Python
    Python 利用高德地图api实现经纬度与地址的批量转换
    2019/08/14 Python
    Django中自定义查询对象的具体使用
    2019/10/13 Python
    python传到前端的数据,双引号被转义的问题
    2020/04/03 Python
    浅谈keras使用预训练模型vgg16分类,损失和准确度不变
    2020/07/02 Python
    python使用列表的最佳方案
    2020/08/12 Python
    Python 可视化神器Plotly详解
    2020/12/26 Python
    用CSS3的box-reflect来制作倒影效果
    2016/11/15 HTML / CSS
    利用HTML5 Canvas API绘制矩形的超级攻略
    2016/03/21 HTML / CSS
    职业技术学校毕业生推荐信
    2013/12/03 职场文书
    幼师求职信
    2014/06/23 职场文书
    2014年中秋寄语
    2014/08/11 职场文书
    2015年基层党建工作汇报材料
    2015/06/25 职场文书
    python 如何在 Matplotlib 中绘制垂直线
    2021/04/02 Python
    SqlServer数据库远程连接案例教程
    2021/07/15 SQL Server
    用Python可视化新冠疫情数据
    2022/01/18 Python
    Java实现简单小画板
    2022/06/10 Java/Android