当你使用 Laravel 来处理共享托管时,其中一个主要问题是你无法直接将主机配置到 public 文件夹。
我们的场景是相同的:
开发环境: 使用基本的 Laravel 配置,没有更改,这样你就可以使用 artisan serve 或 valet 来服务你的应用。
root@localmachine:~# php artisan serve
生产环境: 添加下面的修复程序,以允许 Laravel 在通常由 Apache 安装提供的子目录中工作。
开始吧,重定向所有请求!
首先,在 Laravel 应用程序的根文件夹中创建一个 .htaccess 文件,该文件将重定向所有请求到你的应用程序的 public 文件夹,如果你使用 valet 或 artisan serve,则默认情况下会使用此文件。
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^(.*)$ public/$1 [L]
</IfModule>
现在,如果你尝试在子文件夹中访问你的应用程序:
http://localhost/laravel_subdir
所有的都工作正常,但如果你使用 asset 或 mix 函数,它们将返回错误的路径,例如:
asset('css/app.css')
将返回:
http://localhost/css/app.css
这是因为 asset 和 mix 函数使用 baseRoot 来构建路径,这在使用 valet 或 artisan serve 时是正确的,但在使用 apache 时是错误的。我们的目标是编写一个可以在两个环境中都能正常工作的代码。
这就是窍门!
将 APP_DIR 环境变量添加到你的 .env 文件中,其中包含 Laravel 安装的子目录,如下所示:
APP_NAME=Laravel
APP_ENV=local
APP_DIR = "laravel_subdir"
APP_KEY=base64:56qPq0000qqQv3yAo000NmCH83yEUS6nFRb8Fj0/PyI=
APP_DEBUG=true
APP_URL=http://localhost/laravel_subdir
然后创建一个 Helper Provider 来定义我们的自定义函数,在 Providers 目录中创建一个名为 HelperServiceProvider.php 的文件,并使用以下代码:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;class HelperServiceProvider extends ServiceProvider{/**
* Bootstrap services.
*
* @return void
*/
public function boot(){}/**
* Register services.
*
* @return void
*/
public function register(){ foreach (glob(app_path() . '/Helpers/*.php') as $file) { require_once($file); }}
}
然后,在 App 目录的级别上,添加 Helpers 目录,并在其中创建一个名为 SubdirectoryAssetsHelper.php 的文件,并使用以下代码:
<?phpif (! function_exists('subdirAsset')) {function subdirAsset($path){return asset( (App::environment('production') ? env('APP_DIR') : '')."/".$path);}}if (! function_exists('subdirMix')) {function subdirMix($path){return mix( (App::environment('production') ? env('APP_DIR') : '')."/".$path);}}
现在通过将以下行添加到 config/app.php 文件中来注册提供程序:
App\Providers\HelperServiceProvider::class,
现在替换文件 RouteServiceProvider.php 中的函数 mapWebRoutes,如下所示:
/**
* Define the "web" routes for the application.
*
* These routes all receive session state, CSRF protection, etc.
*
* @return void
*/protected function mapWebRoutes(){ Route::prefix(App::environment('production') ? env('APP_DIR') : '') ->middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));}
并在文件顶部导入 App 类:
use App;
这就是全部,现在你可以在你的 blade 文件中使用函数 subdirAsset 来代替 asset 和 subdirMix 来代替 mix。
切换环境
如果你使用 valet 或 artisan serve,请将你的 APP_ENV 变量保持为“local”:
APP_ENV = local
如果你在共享托管的生产环境中,请使用:
APP_ENV = production
演示
请克隆我的演示 repo:https://github.com/lucabecchetti/laravel_subdir
评论(0)