Laravel 安装在子文件夹和地平线中不起作用

use*_*153 2 laravel laravel-horizon

我已将 Laravel 安装在子文件夹中,并正在尝试安装 Horizo​​n。路由到“test.com/sub-folder/horizo​​n”后,所有损坏的设计以及内部链接都指向主域而不是主域无子文件夹。

经过搜索,这似乎是已知问题,github问题中已经报告了

当 Laravel 安装在子文件夹中时,是否有任何解决方法可以使 Horizo​​n 工作?

Raf*_*ero 5

我有一个仅涉及 PHP 的解决方案。

正如 @Isaiahiroko 所指出的,这个问题是basePath为 Horizo​​n 的界面定义的。该代码位于Laravel\Horizon\Http\Controllers\HomeController::index(). 这个想法是这样的:我们将把我们自己的控制器实现传递给 Laravel 的服务容器,它将覆盖basePath传递给 Horizo​​n 接口的定义。

使用如下代码创建一个新控制器:

<?php

namespace App\Http\Controllers;

use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Str;
use Illuminate\View\View;
use Laravel\Horizon\Horizon;
use Laravel\Horizon\Http\Controllers\HomeController;

class HorizonHomeController extends HomeController
{
    /**
     * Overrides default horizon route to support subdirectory hosting.
     */
    public function index ()
    {
        // We use a plain request to check for the base url.
        $request = request();

        // Set up our base path. 
        $base_path = Str::substr($request->getBasePath(), 1);
        if (!empty($base_path)) {
            $base_path .= '/';
        }

        // Patch default horizon variables with our own base path.
        $variables = Horizon::scriptVariables();
        $variables['path'] = $base_path . config('horizon.path');

        // Render horizon's home view.
        return view('horizon::layout', [
            'assetsAreCurrent'       => Horizon::assetsAreCurrent(),
            'horizonScriptVariables' => $variables,
            'cssFile'                => Horizon::$useDarkTheme ? 'app-dark.css' : 'app.css',
            'isDownForMaintenance'   => App::isDownForMaintenance(),
        ]);
    }
}
Run Code Online (Sandbox Code Playgroud)

剩下的就是告诉 Laravel 的服务容器,当 Horizo​​n 的服务容器HomeController被请求时,它应该提供我们的HorizonHomeController类。在您的AppServiceProvider方法末尾register(),进行以下设置:

// [...]
class AppServiceProvider extends ServiceProvider
{
  // [...]
  /**
   * Register any application services.
   *
   * @return void
   * @throws InvalidConfiguration
   */
  public function register()
  {
    // [...]
    
    // Horizon's subdirectory hack
    $this->app->bind(
      Laravel\Horizon\Http\Controllers\HomeController::class, 
      App\Http\Controllers\HorizonHomeController::class
    );
  }
  
  // [...]
}
Run Code Online (Sandbox Code Playgroud)

之后,您应该可以http(s)://<your-host>/<your-sub-dir>/horizon正常浏览。

注意事项:

对我来说,这比修补已编译的 js 感觉更干净,这也有每次更新 Horizo​​n 时都需要重新应用的缺点(这可以通过 中的更新后脚本来缓解composer)。另外,对于其他要点,此解决方案仅覆盖渲染视图的方法,而不覆盖路由,这意味着 Horizo​​n 的所有身份验证机制(中间件和门)都按照文档中的描述完全工作。