omergy/laravel-apps

Laravel 多应用支持。

0.10.0 2024-10-02 08:58 UTC

This package is not auto-updated.

Last update: 2024-10-03 07:20:10 UTC


README

Latest Version on Packagist Software License tests StyleCI SymfonyInsight Grade Quality Score Code Coverage Total Downloads

此包为 Laravel 多应用提供基本支持。

安装

您可以使用 Composer 管理器安装此包。

$ composer require elfsundae/laravel-apps

对于低于 v5.5 的 Laravel,您需要手动注册服务提供者。

ElfSundae\Apps\AppsServiceProvider::class,

然后发布 配置文件 到您的 config 目录。

$ php artisan vendor:publish --tag=laravel-apps

配置

url 配置选项定义了每个应用的根 URL。

'url' => [
    'web' => 'https://example.com',
    'admin' => 'https://example.com/admin',
    'mobile' => 'https://m.example.com',
    'api' => 'https://api.example.com',
    'assets' => 'https://assets.foo.net',
],

providers 数组列出了每个应用的服务提供者的类名,您可能需要配置为 选择性注册服务提供者

您可以使用 config 选项来覆盖每个应用的默认配置。另外,您可能希望将所有应用默认设置放在一个地方,而不是编辑单独的配置文件,只需将它们放在 default 键中。

'config' => [

    'default' => [
        'app.timezone' => 'Asia/Shanghai',
        'app.log' => env('APP_LOG', 'daily'),
        'app.log_max_files' => 50,
        'filesystems.disks.public.url' => env('APP_URL_ASSETS', env('APP_URL')).'/storage',

        'debugbar.options.auth.show_name' => false,
        'debugbar.options.route.label' => false,
    ],

    'admin' => [
        'auth.defaults' => [
            'guard' => 'admin',
            'passwords' => 'admin_users',
        ],
        'filesystems.default' => 'public',
        'session.domain' => env('SESSION_DOMAIN_ADMIN', null),
    ],

    'api' => [
        'auth.defaults.guard' => 'api',
        'filesystems.default' => 's3',
    ],

],

使用

获取应用管理器实例

您可以使用 Apps 门面、apps() 辅助函数或注入 ElfSundae\Apps\AppManager 依赖项来获取应用管理器实例。

检索应用 URL 配置

use ElfSundae\Apps\Facades\Apps;

// Get all application URLs
Apps::urls();

// Get all application identifiers
apps()->ids();

// Get URL root for the assets app
apps()->root('assets');

// Get URL domain for the api app
apps()->domain('api');

// Get URL prefix for the admin app
apps()->prefix('admin');

确定当前应用标识符

您可以通过应用管理器上的 id 方法或相应的 app_id 辅助函数确定当前请求的应用标识符。

$appId = Apps::id();

$appId = app_id();

您还可以向 id 方法传递参数以检查当前应用标识符是否与给定的值匹配。如果标识符与给定的任何值匹配,则方法将返回 true

if (Apps::id('admin')) {
    // Currently requesting admin app
}

if (app_id('web', 'admin')) {
    // Currently requesting either web app OR admin app
}

选择性注册服务提供者

您可以选择性地为某些子应用注册服务提供者而不是将所有服务提供者添加到 config/app.php 文件中。要这样做,只需在 config/apps.php 配置文件中的 providers 数组中列出提供者即可。

'providers' => [

    'admin' => [
        Rap2hpoutre\LaravelLogViewer\LaravelLogViewerServiceProvider::class,
        Yajra\DataTables\DataTablesServiceProvider::class,
        App\Providers\AdminServiceProvider::class,
    ],

    'api' => [
        App\Providers\ApiServiceProvider::class,
    ],

],

⚠️ 如果您的应用程序运行在 Laravel 5.5+ 上,该版本支持 包发现,您还需要在 composer.json 文件中禁用可选包的发现。

"extra": {
    "laravel": {
        "dont-discover": [
            "rap2hpoutre/laravel-log-viewer",
            "yajra/laravel-datatables-oracle"
        ]
    }
}

不要担心 延迟服务提供者,因为延迟提供者仅在需要时才会加载。

定义应用路由

应用管理器上的 routes 方法可以帮助您为每个应用定义路由组。通常,您会在 RouteServiceProvidermap 方法中调用它。

class RouteServiceProvider extends ServiceProvider
{
    protected $namespace = 'App\Http\Controllers';

    /**
     * Define the routes for the application.
     *
     * @return void
     */
    public function map()
    {
        apps()->routes();
    }
}

带有应用标识符命名的路由文件将自动加载,例如 routes/web.phproutes/admin.php

默认情况下,routes 方法将分配以应用标识符或 web 命名的中间件组到路由组,并将应用标识符的 StudlyCase 应用到控制器路由的命名空间。

例如,apps()->routes() 等同于

// web: https://example.com
Route::group([
    'domain' => 'example.com',
    'middleware' => 'web',
    'namespace' => $this->namespace.'\Web',
], function ($router) {
    require base_path('routes/web.php');
});

// api: https://api.example.com
Route::group([
    'domain' => 'api.example.com',
    'middleware' => 'api',
    'namespace' => $this->namespace.'\Api',
], function ($router) {
    require base_path('routes/api.php');
});

// admin: https://example.com/admin
Route::group([
    'domain' => 'example.com',
    'prefix' => 'admin',
    'middleware' => 'web', // suppose if the "admin" middleware group does not exist
    'namespace' => $this->namespace.'\Admin',
], function ($router) {
    require base_path('routes/admin.php');
});

// ...

当然,您可以自由指定任何路由属性

apps()->routes([
    'web' => [
        'namespace' => $this->namespace,
    ],
    'admin' => [
        'middleware' => ['web', 'admin.ip'],
        'as' => 'admin.',
        'where' => [
            'id' => '[0-9]+',
        ],
    ],
]);

除了数组之外,您还可以将闭包传递给 routes 方法

apps()->routes(function ($id, $apps) {
    return ['as' => $id.'.'];
});

生成 URL

您可以使用 url 方法或相应的 app_url 辅助函数来生成指定应用的路径的绝对URL。

apps()->url('admin', 'user', [$user]); // https://example.com/admin/user/123

app_url('api', 'posts'); // https://api.example.com/posts

asset 方法生成以 assets 应用根URL为前缀的URL。

apps()->asset('js/app.js'); // https://assets.foo.net/js/app.js

为 asset() 辅助函数定义自定义根 URL

Laravel 内置的 URL::asset 方法或相应的 assetsecure_asset 辅助函数旨在生成应用资产的URL。在大多数应用中,我们可能会指定无Cookie的域名或使用CDN来存储资产,但我们无法为这些内置资产方法设置自定义的根URL,目前也没有优雅的方式来扩展核心的 UrlGenerator

您可以使用 URL::assetFromApps::asset 或自定义辅助函数来生成资产URL,但是将所有第三方包中的 asset() 调用替换为自己的资产方法是非常繁琐的。可能更好的解决方案是覆盖内置的 asset 辅助函数:在包含Composer自动加载文件之前,在您的 public/index.php 文件中定义您的 asset 函数。

function asset($path, $secure = null)
{
    return apps()->asset($path, $secure);
}

require __DIR__.'/../vendor/autoload.php';

此软件包附带一个 asset.php 文件,您可以使用它来为 asset() 辅助函数指定 assets 应用的根URL。

require __DIR__.'/../vendor/elfsundae/laravel-apps/asset.php';

require __DIR__.'/../vendor/autoload.php';

提醒一下,相关的PR laravel/framework#22372

扩展应用管理器

AppManager 类是可宏定义的,这意味着您可以使用 macro 方法来扩展它。

Apps::macro('route', function ($name, $parameters = []) {
    return URL::route($this->id().'.'.$name, $parameters);
});

测试

$ composer test

许可证

此软件包是开源软件,许可协议为 MIT 许可协议