如何在Laravel 5中构建模块化应用程序?


72

我想将我的应用程序划分为模块。例如,将有一个“核心”模块,其中包含基本的登录功能,应用程序布局/格式(CSS等),用户管理和日记。

稍后,我可以创建其他模块,例如联系人管理器,可以轻松地从应用程序中添加或删除它们。

应用程序导航中将存在一些逻辑,用于确定存在哪些模块并显示/隐藏到它们的链接。

我该如何在目录结构,名称空间和其他所需的方面做到这一点?


我正在查看creolab / laravel-modules,但它指出它适用于Laravel4。我是否仍可以以完全相同的方式将它与5一起使用?

该文档说要在每个模块目录中放置模型,控制器和视图,但是这如何与路径一起使用?理想情况下,我希望每个模块都有其自己的route.php文件。所有这些如何处理httpresources目录中的内容?


我在想这样的事情:

模块的想法

但是我不知道该如何工作。


我刚刚在这里尝试了本教程:

http://creolab.hr/2013/05/modules-in-laravel-4/

没有额外的库等,只有纯Laravel 5。

我似乎遇到了错误消息:

FatalErrorException in ServiceProvider.php line 16:
Call to undefined method Illuminate\Config\Repository::package()

关于以下内容:

<?php namespace App\Modules;

abstract class ServiceProvider extends \Illuminate\Support\ServiceProvider
{

    public function boot()
    {
        if ($module = $this->getModule(func_get_args())) {
            $this->package('app/' . $module, $module, app_path() . '/modules/' . $module);
        }
    }

    public function register()
    {
        if ($module = $this->getModule(func_get_args())) {
            $this->app['config']->package('app/' . $module, app_path() . '/modules/' . $module . '/config');

// Add routes
            $routes = app_path() . '/modules/' . $module . '/routes.php';
            if (file_exists($routes)) require $routes;
        }
    }

    public function getModule($args)
    {
        $module = (isset($args[0]) and is_string($args[0])) ? $args[0] : null;

        return $module;
    }

}

是什么原因造成的,我该如何解决?


现在,我对此有了更多的了解。得到了我的包/模块路线和视图,这很棒:

abstract class ServiceProvider extends \Illuminate\Support\ServiceProvider
{

    public function boot()
    {
        if ($module = $this->getModule(func_get_args())) {
            include __DIR__.'/'.$module.'/routes.php';
        }
        $this->loadViewsFrom(__DIR__.'/'.$module.'/Views', 'core');
    }

    public function register()
    {
        if ($module = $this->getModule(func_get_args())) {

        }
    }

    public function getModule($args)
    {
        $module = (isset($args[0]) and is_string($args[0])) ? $args[0] : null;

        return $module;
    }

}

我还有最后一个问题,如何从包中加载所有控制器,就像该loadViewsFrom()方法的工作原理一样?


1
虽然这个问题实际上很有趣,但却是一个广泛的问题。引用接近的原因:对于这种格式,可能答案太多,或者好的答案太长。请添加详细信息以缩小答案范围或隔离可以在几段中回答的问题。(我没有投票,但投票决定关闭)
lukasgeiter 2015年

1
@lukasgeiter我添加了更多细节。
imperium2335

奥特威尔先生将HMVC视为反模式。由于您在Laravel 5中具有PSR-4,因此可以自由地模拟带有名称空间的模块。然后,您应该将模块控制器绑定到视图编辑器。laravel.com/docs/5.0/views#view-composers
user2094178

@ user2094178您是否有使用这种方法的模块化方法的示例?我已经用Google搜索了一下,却没有发现详细描述自定义模块化应用程序的任何内容:(
imperium2335

尽管我们这里有一个一般性的指导原则,即问题不应该太宽泛或不讲究,但我认为这是足够的灰色区域,可以避免关闭(IMO)。我认为有趣/新颖会有所帮助。如果您将来自己找到解决方案,请将其发布为答案。
2015年

Answers:


35

我似乎已经想通了。

我将其张贴在这里,以防它对其他初学者有所帮助,这只是关于正确命名空间。

在我的composer.json中,我有:

...
"autoload": {
    "classmap": [
        "database",
        "app/Modules"
    ],
    "psr-4": {
        "App\\": "app/",
        "Modules\\": "Modules/"
    }
}

我的目录和文件最终像这样:

在此处输入图片说明

我通过将我的模块控制器包装在指定名称空间的组中来使我的核心模块router.php工作:

Route::group(array('namespace' => 'Modules\Core'), function() {
    Route::get('/test', ['uses' => 'TestController@index']);
});

我想当我要为程序包做模型时,会出现类似的正确命名空间的情况。

多谢您的协助与耐心!


1
感谢您提出的问题以及为找出答案所做的所有努力。这正是我所需要的。在我看来,Laravel 5结构非常适合中小型应用程序。但是,对于具有不同模块和不同开发人员的大型项目,模块化L5应用程序至关重要@ imperium2335
DucCuong 2015年

1
Route :: group(array('namespace'=>'Modules \ Admin'),function(){Route :: get('/ admin / dashboard','AdminController @ index');}); 这总是返回错误“ Class Modules \ Admin \ AdminController不存在”。我具有相同的文件夹结构,而我的问题已经在这里。 stackoverflow.com/questions/33996528/routing-in-laravel-module / ...如果有人可以找到解决方案,那就太好了。
我是nidhin 2015年

14

解:

步骤1:在“ app /”中创建文件夹“ Modules”


步骤2:在Modules文件夹中,创建您的Module(Module1(假设为admin Module))

 Inside admin module : create the following folder 

 1. Controllers  (here will your controller files)
 2. Views  (here will your View files)
 3. Models  (here will your Model files)
 4. routes.php (here will your route code in this file)

同样,您可以创建多个模块

Module2( suppose API )
-Controllers
-Views
-Models
-routes.php

步骤3:在“模块/”文件夹中创建ModulesServiceProvider.php


步骤4:将以下代码粘贴到ModulesServiceProvider.php中

<?php

namespace App\Modules;

/**
 * ServiceProvider
 *
 * The service provider for the modules. After being registered
 * it will make sure that each of the modules are properly loaded
 * i.e. with their routes, views etc.
 *
 * @author kundan Roy <query@programmerlab.com>
 * @package App\Modules
 */

use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;

class ModulesServiceProvider extends ServiceProvider {

    /**
     * Will make sure that the required modules have been fully loaded
     *
     * @return void routeModule
     */
    public function boot() {
        // For each of the registered modules, include their routes and Views
        $modules=config("module.modules");

        while (list(,$module)=each($modules)) {

            // Load the routes for each of the modules

            if (file_exists(DIR.'/'.$module.'/routes.php')) {

                include DIR.'/'.$module.'/routes.php';
            }

            if (is_dir(DIR.'/'.$module.'/Views')) {
                $this->loadViewsFrom(DIR.'/'.$module.'/Views',$module);
            }
        }
    }

    public function register() { }

}

步骤5:在“ config / app.php”文件中添加以下行

App\Modules\ModulesServiceProvider::class,

步骤6:在“ config”文件夹中创建module.php文件

步骤7:在module.php中添加以下代码(路径=>“ config / module.php”)

<?php

return [
    'modules'=>[
        'admin',
        'web',
        'api'
    ]
];

注意:您可以添加创建的模块名称。这里有模块。

步骤8:运行此命令

composer dump-autoload

8

有点晚了,但是如果您想在将来的项目中使用模块,我已经编写了一个模块生成器。它可以通过生成模块。php artisan make:module name您也可以在其中添加一些模块app/Modules文件夹中,以备使用/使用。看一看。节省一些时间;)

l5模块化


1
是否可以使用中央GUI启用或禁用模块?还是您的结构不合适?
Aschwin Wesselius

2
“中央GUI”是什么意思?默认情况下,您可以禁用相应app/config/modules.php文件中的模块。如果您需要动态管理模块,我建议您分叉git并根据需要修改ModuleServiceProvider.php(第19行)(FA。从DB获取模块加载列表)。
Gordon Freeman

2
您也可以modules.enable在运行时设置配置。F A。config(['modules.enable' => ['customer', 'contract', 'reporting']]);
Gordon Freeman

@GordonFreeman:我检查了你的工作。在安装过程中,您说过要在composer.json中添加一行。但是您没有告诉在composer.json中应该在哪一行以及什么位置添加该行?
saadk '16

2
@saadk,必须将行添加到require节点中。就像您通过composer安装的所有其他php-package一样。看看docs getcomposer.org/doc/04-schema.md#package-links
Gordon Freeman


2

Kundan roy:我喜欢您的解决方案,但是我从StackOverflow复制了您的代码,我不得不更改引号和半引号以使其正常工作-我认为SOF可以代替它们。还将base_path()的Dir更改为与Laravel的(新)格式更加内联。

namespace App\Modules;

/**
* ServiceProvider
*
* The service provider for the modules. After being registered
* it will make sure that each of the modules are properly loaded
* i.e. with their routes, views etc.
*
* @author kundan Roy <query@programmerlab.com>
* @package App\Modules
*/

use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;

class ModulesServiceProvider extends ServiceProvider
{

/**
* Will make sure that the required modules have been fully loaded
* @return void routeModule
*/
   public function boot()
{
    // For each of the registered modules, include their routes and Views
    $modules = config("module.modules");

    while (list(,$module) = each($modules)) {

        // Load the routes for each of the modules
        if(file_exists(base_path('app/Modules/'.$module.'/routes.php'))) {
            include base_path('app/Modules/'.$module.'/routes.php');
        }

        // Load the views                                           
        if(is_dir(base_path('app/Modules/'.$module.'/Views'))) {
            $this->loadViewsFrom(base_path('app/Modules/'.$module.'/Views'), $module);
        }
    }
}

public function register() {}

}

0

pingpong/modules是一个laravel软件包,用于使用模块管理大型laravel应用。模块就像laravel软件包一样,结构简单,它具有一些视图,控制器或模型。

它可以在Laravel 4和Laravel 5中使用。

要通过composer安装,只需将以下内容放入composer.json文件中:

{
    "require": {
        "pingpong/modules": "~2.1"
    }
}

然后运行composer install以获取软件包。

要创建一个新模块,您可以简单地运行:

php artisan module:make <module-name>

-必填。将创建模块的名称。创建一个新模块

php artisan module:make Blog

创建多个模块

php artisan module:make Blog User Auth

欲了解更多信息,请访问:https : //github.com/pingpong-labs/modules

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.